Search in sources :

Example 21 with BitSetRecyclable

use of org.apache.pulsar.common.util.collections.BitSetRecyclable in project pulsar by apache.

the class PositionAckSetUtilTest method andAckSetTest.

@Test
public void andAckSetTest() {
    PositionImpl positionOne = PositionImpl.get(1, 1);
    PositionImpl positionTwo = PositionImpl.get(1, 2);
    BitSet bitSetOne = new BitSet();
    BitSet bitSetTwo = new BitSet();
    bitSetOne.set(0);
    bitSetOne.set(2);
    bitSetOne.set(4);
    bitSetOne.set(6);
    bitSetOne.set(8);
    positionOne.setAckSet(bitSetOne.toLongArray());
    positionTwo.setAckSet(bitSetTwo.toLongArray());
    andAckSet(positionOne, positionTwo);
    BitSetRecyclable bitSetRecyclable = BitSetRecyclable.valueOf(positionOne.getAckSet());
    assertTrue(bitSetRecyclable.isEmpty());
    bitSetTwo.set(2);
    bitSetTwo.set(4);
    positionOne.setAckSet(bitSetOne.toLongArray());
    positionTwo.setAckSet(bitSetTwo.toLongArray());
    andAckSet(positionOne, positionTwo);
    bitSetRecyclable = BitSetRecyclable.valueOf(positionOne.getAckSet());
    BitSetRecyclable bitSetRecyclableTwo = BitSetRecyclable.valueOf(bitSetTwo.toLongArray());
    assertEquals(bitSetRecyclable, bitSetRecyclableTwo);
}
Also used : BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) BitSet(java.util.BitSet) Test(org.testng.annotations.Test)

Example 22 with BitSetRecyclable

use of org.apache.pulsar.common.util.collections.BitSetRecyclable in project pulsar by apache.

the class PendingAckInMemoryDeleteTest method txnAckTestBatchAndSharedSubMemoryDeleteTest.

@Test
public void txnAckTestBatchAndSharedSubMemoryDeleteTest() throws Exception {
    String normalTopic = NAMESPACE1 + "/normal-topic";
    String subscriptionName = "test";
    @Cleanup Consumer<byte[]> consumer = pulsarClient.newConsumer().topic(normalTopic).subscriptionName(subscriptionName).enableBatchIndexAcknowledgment(true).subscriptionType(SubscriptionType.Shared).subscribe();
    @Cleanup Producer<byte[]> producer = pulsarClient.newProducer().topic(normalTopic).enableBatching(true).batchingMaxMessages(200).create();
    PendingAckHandleImpl pendingAckHandle = null;
    LinkedMap<TxnID, HashMap<PositionImpl, PositionImpl>> individualAckOfTransaction = null;
    ManagedCursorImpl managedCursor = null;
    MessageId[] messageIds = new MessageId[2];
    for (int retryCnt = 0; retryCnt < 2; retryCnt++) {
        int messageCnt = 1000;
        // produce normal messages
        for (int i = 0; i < messageCnt; i++) {
            producer.newMessage().value("hello".getBytes()).sendAsync();
        }
        Message<byte[]> message;
        // after transaction abort, the messages could be received
        Transaction commitTxn = getTxn();
        // send 1000 and ack 999, and test the consumer pending ack has already clear 999 messages
        for (int i = 0; i < messageCnt; i++) {
            message = consumer.receive(2, TimeUnit.SECONDS);
            Assert.assertNotNull(message);
            // in order to free up 2 position to judge the consumer pending ack delete
            if (i != 500) {
                if (i % 2 == 0) {
                    consumer.acknowledgeAsync(message.getMessageId(), commitTxn).get();
                    log.info("txn receive msgId: {}, count: {}", message.getMessageId(), i);
                } else {
                    consumer.acknowledge(message.getMessageId());
                    log.info("normal receive msgId: {}, count: {}", message.getMessageId(), i);
                }
            } else {
                messageIds[retryCnt] = message.getMessageId();
            }
        }
        commitTxn.commit().get();
        int count = 0;
        for (int i = 0; i < getPulsarServiceList().size(); i++) {
            Field field = BrokerService.class.getDeclaredField("topics");
            field.setAccessible(true);
            ConcurrentOpenHashMap<String, CompletableFuture<Optional<Topic>>> topics = (ConcurrentOpenHashMap<String, CompletableFuture<Optional<Topic>>>) field.get(getPulsarServiceList().get(i).getBrokerService());
            CompletableFuture<Optional<Topic>> completableFuture = topics.get("persistent://" + normalTopic);
            if (completableFuture != null) {
                Optional<Topic> topic = completableFuture.get();
                if (topic.isPresent()) {
                    PersistentSubscription testPersistentSubscription = (PersistentSubscription) topic.get().getSubscription(subscriptionName);
                    field = PersistentSubscription.class.getDeclaredField("pendingAckHandle");
                    field.setAccessible(true);
                    pendingAckHandle = (PendingAckHandleImpl) field.get(testPersistentSubscription);
                    field = PendingAckHandleImpl.class.getDeclaredField("individualAckOfTransaction");
                    field.setAccessible(true);
                    individualAckOfTransaction = (LinkedMap<TxnID, HashMap<PositionImpl, PositionImpl>>) field.get(pendingAckHandle);
                    assertTrue(individualAckOfTransaction.isEmpty());
                    managedCursor = (ManagedCursorImpl) testPersistentSubscription.getCursor();
                    field = ManagedCursorImpl.class.getDeclaredField("batchDeletedIndexes");
                    field.setAccessible(true);
                    final ConcurrentSkipListMap<PositionImpl, BitSetRecyclable> batchDeletedIndexes = (ConcurrentSkipListMap<PositionImpl, BitSetRecyclable>) field.get(managedCursor);
                    if (retryCnt == 0) {
                        // one message are not ack
                        Awaitility.await().until(() -> {
                            return testPersistentSubscription.getConsumers().get(0).getPendingAcks().size() == 1;
                        });
                        assertEquals(batchDeletedIndexes.size(), 1);
                        assertEquals(testPersistentSubscription.getConsumers().get(0).getPendingAcks().size(), 1);
                    } else {
                        // two message are not ack
                        Awaitility.await().until(() -> {
                            return testPersistentSubscription.getConsumers().get(0).getPendingAcks().size() == 2;
                        });
                        Transaction commitTwice = getTxn();
                        // this message is in one batch point
                        consumer.acknowledge(messageIds[0]);
                        Awaitility.await().until(() -> {
                            return batchDeletedIndexes.size() == 1;
                        });
                        assertEquals(testPersistentSubscription.getConsumers().get(0).getPendingAcks().size(), 1);
                        // this test is for the last message has been cleared in this consumer pending acks
                        // and it won't clear the last message in cursor batch index ack set
                        consumer.acknowledgeAsync(messageIds[1], commitTwice).get();
                        assertEquals(batchDeletedIndexes.size(), 1);
                        assertEquals(testPersistentSubscription.getConsumers().get(0).getPendingAcks().size(), 0);
                        // the messages has been produced were all acked, the memory in broker for the messages has been cleared.
                        commitTwice.commit().get();
                        assertEquals(batchDeletedIndexes.size(), 0);
                        assertEquals(testPersistentSubscription.getConsumers().get(0).getPendingAcks().size(), 0);
                    }
                    count++;
                }
            }
        }
        assertEquals(count, 1);
    }
}
Also used : ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) HashMap(java.util.HashMap) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) Cleanup(lombok.Cleanup) Field(java.lang.reflect.Field) CompletableFuture(java.util.concurrent.CompletableFuture) Topic(org.apache.pulsar.broker.service.Topic) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Optional(java.util.Optional) PendingAckHandleImpl(org.apache.pulsar.broker.transaction.pendingack.impl.PendingAckHandleImpl) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) TxnID(org.apache.pulsar.client.api.transaction.TxnID) Transaction(org.apache.pulsar.client.api.transaction.Transaction) MessageId(org.apache.pulsar.client.api.MessageId) Test(org.testng.annotations.Test)

Aggregations

BitSetRecyclable (org.apache.pulsar.common.util.collections.BitSetRecyclable)22 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)7 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)3 ManagedLedgerException.getManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException.getManagedLedgerException)3 ManagedCursorImpl (org.apache.bookkeeper.mledger.impl.ManagedCursorImpl)3 ManagedLedgerImpl.createManagedLedgerException (org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.createManagedLedgerException)3 Test (org.testng.annotations.Test)3 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)2 ArrayList (java.util.ArrayList)2 Collections (java.util.Collections)2 List (java.util.List)2 Optional (java.util.Optional)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 BKException (org.apache.bookkeeper.client.BKException)2 AsyncCallbacks (org.apache.bookkeeper.mledger.AsyncCallbacks)2 MarkDeleteCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.MarkDeleteCallback)2