Search in sources :

Example 1 with PendingAckStore

use of org.apache.pulsar.broker.transaction.pendingack.PendingAckStore in project pulsar by apache.

the class TransactionTest method testSubscriptionRecreateTopic.

@Test
public void testSubscriptionRecreateTopic() throws PulsarAdminException, NoSuchFieldException, IllegalAccessException, PulsarClientException {
    String topic = "persistent://pulsar/system/testReCreateTopic";
    String subName = "sub_testReCreateTopic";
    int retentionSizeInMbSetTo = 5;
    int retentionSizeInMbSetTopic = 6;
    int retentionSizeInMinutesSetTo = 5;
    int retentionSizeInMinutesSetTopic = 6;
    admin.topics().createNonPartitionedTopic(topic);
    PulsarService pulsarService = super.getPulsarServiceList().get(0);
    pulsarService.getBrokerService().getTopics().clear();
    ManagedLedgerFactory managedLedgerFactory = pulsarService.getBrokerService().getManagedLedgerFactory();
    Field field = ManagedLedgerFactoryImpl.class.getDeclaredField("ledgers");
    field.setAccessible(true);
    ConcurrentHashMap<String, CompletableFuture<ManagedLedgerImpl>> ledgers = (ConcurrentHashMap<String, CompletableFuture<ManagedLedgerImpl>>) field.get(managedLedgerFactory);
    ledgers.remove(TopicName.get(topic).getPersistenceNamingEncoding());
    try {
        admin.topics().createNonPartitionedTopic(topic);
        Assert.fail();
    } catch (PulsarAdminException.ConflictException e) {
        log.info("Cann`t create topic again");
    }
    admin.topics().setRetention(topic, new RetentionPolicies(retentionSizeInMinutesSetTopic, retentionSizeInMbSetTopic));
    pulsarClient.newConsumer().topic(topic).subscriptionName(subName).subscribe();
    pulsarService.getBrokerService().getTopicIfExists(topic).thenAccept(option -> {
        if (!option.isPresent()) {
            log.error("Failed o get Topic named: {}", topic);
            Assert.fail();
        }
        PersistentTopic originPersistentTopic = (PersistentTopic) option.get();
        String pendingAckTopicName = MLPendingAckStore.getTransactionPendingAckStoreSuffix(originPersistentTopic.getName(), subName);
        try {
            admin.topics().setRetention(pendingAckTopicName, new RetentionPolicies(retentionSizeInMinutesSetTo, retentionSizeInMbSetTo));
        } catch (PulsarAdminException e) {
            log.error("Failed to get./setRetention of topic with Exception:" + e);
            Assert.fail();
        }
        PersistentSubscription subscription = originPersistentTopic.getSubscription(subName);
        subscription.getPendingAckManageLedger().thenAccept(managedLedger -> {
            long retentionSize = managedLedger.getConfig().getRetentionSizeInMB();
            if (!originPersistentTopic.getTopicPolicies().isPresent()) {
                log.error("Failed to getTopicPolicies of :" + originPersistentTopic);
                Assert.fail();
            }
            TopicPolicies topicPolicies = originPersistentTopic.getTopicPolicies().get();
            Assert.assertEquals(retentionSizeInMbSetTopic, retentionSize);
            MLPendingAckStoreProvider mlPendingAckStoreProvider = new MLPendingAckStoreProvider();
            CompletableFuture<PendingAckStore> future = mlPendingAckStoreProvider.newPendingAckStore(subscription);
            future.thenAccept(pendingAckStore -> {
                ((MLPendingAckStore) pendingAckStore).getManagedLedger().thenAccept(managedLedger1 -> {
                    Assert.assertEquals(managedLedger1.getConfig().getRetentionSizeInMB(), retentionSizeInMbSetTo);
                });
            });
        });
    });
}
Also used : RetentionPolicies(org.apache.pulsar.common.policies.data.RetentionPolicies) TopicPolicies(org.apache.pulsar.common.policies.data.TopicPolicies) MLPendingAckStoreProvider(org.apache.pulsar.broker.transaction.pendingack.impl.MLPendingAckStoreProvider) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) Field(java.lang.reflect.Field) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) CompletableFuture(java.util.concurrent.CompletableFuture) PulsarService(org.apache.pulsar.broker.PulsarService) MLPendingAckStore(org.apache.pulsar.broker.transaction.pendingack.impl.MLPendingAckStore) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) ManagedLedgerFactory(org.apache.bookkeeper.mledger.ManagedLedgerFactory) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) PulsarAdminException(org.apache.pulsar.client.admin.PulsarAdminException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.testng.annotations.Test)

Example 2 with PendingAckStore

use of org.apache.pulsar.broker.transaction.pendingack.PendingAckStore in project pulsar by yahoo.

the class PendingAckHandleImpl method internalIndividualAcknowledgeMessage.

public void internalIndividualAcknowledgeMessage(TxnID txnID, List<MutablePair<PositionImpl, Integer>> positions, CompletableFuture<Void> completableFuture) {
    if (txnID == null) {
        completableFuture.completeExceptionally(new NotAllowedException("Positions can not be null."));
        return;
    }
    if (positions == null) {
        completableFuture.completeExceptionally(new NotAllowedException("Positions can not be null."));
        return;
    }
    this.pendingAckStoreFuture.thenAccept(pendingAckStore -> pendingAckStore.appendIndividualAck(txnID, positions).thenAccept(v -> {
        synchronized (org.apache.pulsar.broker.transaction.pendingack.impl.PendingAckHandleImpl.this) {
            for (MutablePair<PositionImpl, Integer> positionIntegerMutablePair : positions) {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] individualAcknowledgeMessage position: [{}], " + "txnId: [{}], subName: [{}]", topicName, positionIntegerMutablePair.left, txnID, subName);
                }
                PositionImpl position = positionIntegerMutablePair.left;
                // normal acknowledge,throw exception.
                if (((ManagedCursorImpl) persistentSubscription.getCursor()).isMessageDeleted(position)) {
                    String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " already acked before.";
                    log.error(errorMsg);
                    completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                    return;
                }
                if (position.hasAckSet()) {
                    // in order to jude the bit set is over lap, so set the covering
                    // the batch size bit to 1,should know the two
                    // bit set don't have the same point is 0
                    BitSetRecyclable bitSetRecyclable = BitSetRecyclable.valueOf(position.getAckSet());
                    if (positionIntegerMutablePair.right > bitSetRecyclable.size()) {
                        bitSetRecyclable.set(positionIntegerMutablePair.right);
                    }
                    bitSetRecyclable.set(positionIntegerMutablePair.right, bitSetRecyclable.size());
                    long[] ackSetOverlap = bitSetRecyclable.toLongArray();
                    bitSetRecyclable.recycle();
                    if (isAckSetOverlap(ackSetOverlap, ((ManagedCursorImpl) persistentSubscription.getCursor()).getBatchPositionAckSet(position))) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " already acked before.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                    if (individualAckPositions != null && individualAckPositions.containsKey(position) && isAckSetOverlap(individualAckPositions.get(position).getLeft().getAckSet(), ackSetOverlap)) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack batch message:" + position + " in pending ack status.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                } else {
                    if (individualAckPositions != null && individualAckPositions.containsKey(position)) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " in pending ack status.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                }
            }
            handleIndividualAck(txnID, positions);
            completableFuture.complete(null);
        }
    }).exceptionally(e -> {
        synchronized (PendingAckHandleImpl.this) {
            // we also modify the in memory state when append fail,
            // because we don't know the persistent state, when were replay it,
            // it will produce the wrong operation. so we append fail,
            // we should wait tc time out or client abort this transaction.
            handleIndividualAck(txnID, positions);
            completableFuture.completeExceptionally(e.getCause());
        }
        return null;
    })).exceptionally(e -> {
        completableFuture.completeExceptionally(e);
        return null;
    });
}
Also used : ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) Getter(lombok.Getter) LinkedMap(org.apache.commons.collections4.map.LinkedMap) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Consumer(org.apache.pulsar.broker.service.Consumer) ArrayList(java.util.ArrayList) TxnID(org.apache.pulsar.client.api.transaction.TxnID) PositionAckSetUtil.isAckSetOverlap(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.isAckSetOverlap) MutablePair(org.apache.commons.lang3.tuple.MutablePair) Pair(org.apache.commons.lang3.tuple.Pair) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PositionAckSetUtil.compareToWithAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.compareToWithAckSet) ExecutorService(java.util.concurrent.ExecutorService) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Semaphore(java.util.concurrent.Semaphore) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TransactionPendingAckStoreProvider(org.apache.pulsar.broker.transaction.pendingack.TransactionPendingAckStoreProvider) BlockingQueue(java.util.concurrent.BlockingQueue) Position(org.apache.bookkeeper.mledger.Position) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Slf4j(lombok.extern.slf4j.Slf4j) PendingAckHandle(org.apache.pulsar.broker.transaction.pendingack.PendingAckHandle) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PositionAckSetUtil.andAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.andAckSet) TransactionPendingAckStats(org.apache.pulsar.common.policies.data.TransactionPendingAckStats) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) Collections(java.util.Collections) TransactionInPendingAckStats(org.apache.pulsar.common.policies.data.TransactionInPendingAckStats) MutablePair(org.apache.commons.lang3.tuple.MutablePair) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException)

Example 3 with PendingAckStore

use of org.apache.pulsar.broker.transaction.pendingack.PendingAckStore in project incubator-pulsar by apache.

the class PendingAckHandleImpl method internalCumulativeAcknowledgeMessage.

public void internalCumulativeAcknowledgeMessage(TxnID txnID, List<PositionImpl> positions, CompletableFuture<Void> completableFuture) {
    if (txnID == null) {
        completableFuture.completeExceptionally(new NotAllowedException("TransactionID can not be null."));
        return;
    }
    if (positions == null) {
        completableFuture.completeExceptionally(new NotAllowedException("Positions can not be null."));
        return;
    }
    if (positions.size() != 1) {
        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " invalid cumulative ack received with multiple message ids.";
        log.error(errorMsg);
        completableFuture.completeExceptionally(new NotAllowedException(errorMsg));
        return;
    }
    PositionImpl position = positions.get(0);
    this.pendingAckStoreFuture.thenAccept(pendingAckStore -> pendingAckStore.appendCumulativeAck(txnID, position).thenAccept(v -> {
        if (log.isDebugEnabled()) {
            log.debug("[{}] cumulativeAcknowledgeMessage position: [{}], " + "txnID:[{}], subName: [{}].", topicName, txnID, position, subName);
        }
        if (position.compareTo((PositionImpl) persistentSubscription.getCursor().getMarkDeletedPosition()) <= 0) {
            String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to cumulative ack position: " + position + " within range of cursor's " + "markDeletePosition: " + persistentSubscription.getCursor().getMarkDeletedPosition();
            log.error(errorMsg);
            completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
            return;
        }
        if (cumulativeAckOfTransaction != null && (!cumulativeAckOfTransaction.getKey().equals(txnID) || compareToWithAckSet(position, cumulativeAckOfTransaction.getValue()) <= 0)) {
            String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to cumulative batch ack position: " + position + " within range of current " + "currentPosition: " + cumulativeAckOfTransaction.getValue();
            log.error(errorMsg);
            completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
            return;
        }
        handleCumulativeAck(txnID, position);
        completableFuture.complete(null);
    }).exceptionally(e -> {
        // we also modify the in memory state when append fail, because we don't know the persistent
        // state, when wereplay it, it will produce the wrong operation. so we append fail, we should
        // wait tc time out or client abort this transaction.
        handleCumulativeAck(txnID, position);
        completableFuture.completeExceptionally(e.getCause());
        return null;
    })).exceptionally(e -> {
        completableFuture.completeExceptionally(e);
        return null;
    });
}
Also used : ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) Getter(lombok.Getter) LinkedMap(org.apache.commons.collections4.map.LinkedMap) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Consumer(org.apache.pulsar.broker.service.Consumer) ArrayList(java.util.ArrayList) TxnID(org.apache.pulsar.client.api.transaction.TxnID) PositionAckSetUtil.isAckSetOverlap(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.isAckSetOverlap) MutablePair(org.apache.commons.lang3.tuple.MutablePair) Pair(org.apache.commons.lang3.tuple.Pair) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PositionAckSetUtil.compareToWithAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.compareToWithAckSet) ExecutorService(java.util.concurrent.ExecutorService) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Semaphore(java.util.concurrent.Semaphore) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TransactionPendingAckStoreProvider(org.apache.pulsar.broker.transaction.pendingack.TransactionPendingAckStoreProvider) BlockingQueue(java.util.concurrent.BlockingQueue) Position(org.apache.bookkeeper.mledger.Position) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Slf4j(lombok.extern.slf4j.Slf4j) PendingAckHandle(org.apache.pulsar.broker.transaction.pendingack.PendingAckHandle) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PositionAckSetUtil.andAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.andAckSet) TransactionPendingAckStats(org.apache.pulsar.common.policies.data.TransactionPendingAckStats) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) Collections(java.util.Collections) TransactionInPendingAckStats(org.apache.pulsar.common.policies.data.TransactionInPendingAckStats) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException)

Example 4 with PendingAckStore

use of org.apache.pulsar.broker.transaction.pendingack.PendingAckStore in project incubator-pulsar by apache.

the class PendingAckHandleImpl method internalIndividualAcknowledgeMessage.

public void internalIndividualAcknowledgeMessage(TxnID txnID, List<MutablePair<PositionImpl, Integer>> positions, CompletableFuture<Void> completableFuture) {
    if (txnID == null) {
        completableFuture.completeExceptionally(new NotAllowedException("Positions can not be null."));
        return;
    }
    if (positions == null) {
        completableFuture.completeExceptionally(new NotAllowedException("Positions can not be null."));
        return;
    }
    this.pendingAckStoreFuture.thenAccept(pendingAckStore -> pendingAckStore.appendIndividualAck(txnID, positions).thenAccept(v -> {
        synchronized (org.apache.pulsar.broker.transaction.pendingack.impl.PendingAckHandleImpl.this) {
            for (MutablePair<PositionImpl, Integer> positionIntegerMutablePair : positions) {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] individualAcknowledgeMessage position: [{}], " + "txnId: [{}], subName: [{}]", topicName, positionIntegerMutablePair.left, txnID, subName);
                }
                PositionImpl position = positionIntegerMutablePair.left;
                // normal acknowledge,throw exception.
                if (((ManagedCursorImpl) persistentSubscription.getCursor()).isMessageDeleted(position)) {
                    String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " already acked before.";
                    log.error(errorMsg);
                    completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                    return;
                }
                if (position.hasAckSet()) {
                    // in order to jude the bit set is over lap, so set the covering
                    // the batch size bit to 1,should know the two
                    // bit set don't have the same point is 0
                    BitSetRecyclable bitSetRecyclable = BitSetRecyclable.valueOf(position.getAckSet());
                    if (positionIntegerMutablePair.right > bitSetRecyclable.size()) {
                        bitSetRecyclable.set(positionIntegerMutablePair.right);
                    }
                    bitSetRecyclable.set(positionIntegerMutablePair.right, bitSetRecyclable.size());
                    long[] ackSetOverlap = bitSetRecyclable.toLongArray();
                    bitSetRecyclable.recycle();
                    if (isAckSetOverlap(ackSetOverlap, ((ManagedCursorImpl) persistentSubscription.getCursor()).getBatchPositionAckSet(position))) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " already acked before.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                    if (individualAckPositions != null && individualAckPositions.containsKey(position) && isAckSetOverlap(individualAckPositions.get(position).getLeft().getAckSet(), ackSetOverlap)) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack batch message:" + position + " in pending ack status.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                } else {
                    if (individualAckPositions != null && individualAckPositions.containsKey(position)) {
                        String errorMsg = "[" + topicName + "][" + subName + "] Transaction:" + txnID + " try to ack message:" + position + " in pending ack status.";
                        log.error(errorMsg);
                        completableFuture.completeExceptionally(new TransactionConflictException(errorMsg));
                        return;
                    }
                }
            }
            handleIndividualAck(txnID, positions);
            completableFuture.complete(null);
        }
    }).exceptionally(e -> {
        synchronized (PendingAckHandleImpl.this) {
            // we also modify the in memory state when append fail,
            // because we don't know the persistent state, when were replay it,
            // it will produce the wrong operation. so we append fail,
            // we should wait tc time out or client abort this transaction.
            handleIndividualAck(txnID, positions);
            completableFuture.completeExceptionally(e.getCause());
        }
        return null;
    })).exceptionally(e -> {
        completableFuture.completeExceptionally(e);
        return null;
    });
}
Also used : ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) Getter(lombok.Getter) LinkedMap(org.apache.commons.collections4.map.LinkedMap) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Consumer(org.apache.pulsar.broker.service.Consumer) ArrayList(java.util.ArrayList) TxnID(org.apache.pulsar.client.api.transaction.TxnID) PositionAckSetUtil.isAckSetOverlap(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.isAckSetOverlap) MutablePair(org.apache.commons.lang3.tuple.MutablePair) Pair(org.apache.commons.lang3.tuple.Pair) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PositionAckSetUtil.compareToWithAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.compareToWithAckSet) ExecutorService(java.util.concurrent.ExecutorService) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) DEFAULT_CONSUMER_EPOCH(org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH) Semaphore(java.util.concurrent.Semaphore) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TransactionPendingAckStoreProvider(org.apache.pulsar.broker.transaction.pendingack.TransactionPendingAckStoreProvider) BlockingQueue(java.util.concurrent.BlockingQueue) Position(org.apache.bookkeeper.mledger.Position) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) Slf4j(lombok.extern.slf4j.Slf4j) PendingAckHandle(org.apache.pulsar.broker.transaction.pendingack.PendingAckHandle) FutureUtil(org.apache.pulsar.common.util.FutureUtil) PositionAckSetUtil.andAckSet(org.apache.bookkeeper.mledger.util.PositionAckSetUtil.andAckSet) TransactionPendingAckStats(org.apache.pulsar.common.policies.data.TransactionPendingAckStats) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) Collections(java.util.Collections) TransactionInPendingAckStats(org.apache.pulsar.common.policies.data.TransactionInPendingAckStats) MutablePair(org.apache.commons.lang3.tuple.MutablePair) ManagedCursorImpl(org.apache.bookkeeper.mledger.impl.ManagedCursorImpl) NotAllowedException(org.apache.pulsar.broker.service.BrokerServiceException.NotAllowedException) BitSetRecyclable(org.apache.pulsar.common.util.collections.BitSetRecyclable) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) TransactionConflictException(org.apache.pulsar.transaction.common.exception.TransactionConflictException)

Example 5 with PendingAckStore

use of org.apache.pulsar.broker.transaction.pendingack.PendingAckStore in project incubator-pulsar by apache.

the class MLPendingAckStoreProvider method newPendingAckStore.

@Override
public CompletableFuture<PendingAckStore> newPendingAckStore(PersistentSubscription subscription) {
    CompletableFuture<PendingAckStore> pendingAckStoreFuture = new CompletableFuture<>();
    if (subscription == null) {
        pendingAckStoreFuture.completeExceptionally(new TransactionPendingAckException.TransactionPendingAckStoreProviderException("The subscription is null."));
        return pendingAckStoreFuture;
    }
    PersistentTopic originPersistentTopic = (PersistentTopic) subscription.getTopic();
    String pendingAckTopicName = MLPendingAckStore.getTransactionPendingAckStoreSuffix(originPersistentTopic.getName(), subscription.getName());
    originPersistentTopic.getBrokerService().getManagedLedgerFactory().asyncExists(TopicName.get(pendingAckTopicName).getPersistenceNamingEncoding()).thenAccept(exist -> {
        TopicName topicName;
        if (exist) {
            topicName = TopicName.get(pendingAckTopicName);
        } else {
            topicName = TopicName.get(originPersistentTopic.getName());
        }
        originPersistentTopic.getBrokerService().getManagedLedgerConfig(topicName).thenAccept(config -> {
            config.setCreateIfMissing(true);
            originPersistentTopic.getBrokerService().getManagedLedgerFactory().asyncOpen(TopicName.get(pendingAckTopicName).getPersistenceNamingEncoding(), config, new AsyncCallbacks.OpenLedgerCallback() {

                @Override
                public void openLedgerComplete(ManagedLedger ledger, Object ctx) {
                    ledger.asyncOpenCursor(MLPendingAckStore.getTransactionPendingAckStoreCursorName(), InitialPosition.Earliest, new AsyncCallbacks.OpenCursorCallback() {

                        @Override
                        public void openCursorComplete(ManagedCursor cursor, Object ctx) {
                            pendingAckStoreFuture.complete(new MLPendingAckStore(ledger, cursor, subscription.getCursor(), originPersistentTopic.getBrokerService().getPulsar().getConfiguration().getTransactionPendingAckLogIndexMinLag()));
                            if (log.isDebugEnabled()) {
                                log.debug("{},{} open MLPendingAckStore cursor success", originPersistentTopic.getName(), subscription.getName());
                            }
                        }

                        @Override
                        public void openCursorFailed(ManagedLedgerException exception, Object ctx) {
                            log.error("{},{} open MLPendingAckStore cursor failed.", originPersistentTopic.getName(), subscription.getName(), exception);
                            pendingAckStoreFuture.completeExceptionally(exception);
                        }
                    }, null);
                }

                @Override
                public void openLedgerFailed(ManagedLedgerException exception, Object ctx) {
                    log.error("{}, {} open MLPendingAckStore managedLedger failed.", originPersistentTopic.getName(), subscription.getName(), exception);
                    pendingAckStoreFuture.completeExceptionally(exception);
                }
            }, () -> true, null);
        });
    }).exceptionally(e -> {
        log.error("Failed to obtain the existence of ManagerLedger with topic and subscription : " + originPersistentTopic.getSubscriptions() + "  " + subscription.getName());
        pendingAckStoreFuture.completeExceptionally(e.getCause());
        return null;
    });
    return pendingAckStoreFuture;
}
Also used : TopicName(org.apache.pulsar.common.naming.TopicName) TransactionPendingAckException(org.apache.pulsar.broker.transaction.exception.pendingack.TransactionPendingAckException) InitialPosition(org.apache.pulsar.common.api.proto.CommandSubscribe.InitialPosition) TransactionPendingAckStoreProvider(org.apache.pulsar.broker.transaction.pendingack.TransactionPendingAckStoreProvider) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) Slf4j(lombok.extern.slf4j.Slf4j) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) PersistentSubscription(org.apache.pulsar.broker.service.persistent.PersistentSubscription) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) TopicName(org.apache.pulsar.common.naming.TopicName) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) TransactionPendingAckException(org.apache.pulsar.broker.transaction.exception.pendingack.TransactionPendingAckException)

Aggregations

CompletableFuture (java.util.concurrent.CompletableFuture)15 PendingAckStore (org.apache.pulsar.broker.transaction.pendingack.PendingAckStore)15 PersistentSubscription (org.apache.pulsar.broker.service.persistent.PersistentSubscription)12 TransactionPendingAckStoreProvider (org.apache.pulsar.broker.transaction.pendingack.TransactionPendingAckStoreProvider)12 ArrayList (java.util.ArrayList)9 List (java.util.List)9 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)9 Slf4j (lombok.extern.slf4j.Slf4j)9 ManagedLedger (org.apache.bookkeeper.mledger.ManagedLedger)9 ManagedCursorImpl (org.apache.bookkeeper.mledger.impl.ManagedCursorImpl)9 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)9 Consumer (org.apache.pulsar.broker.service.Consumer)9 TxnID (org.apache.pulsar.client.api.transaction.TxnID)9 AckType (org.apache.pulsar.common.api.proto.CommandAck.AckType)9 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)7 Collections (java.util.Collections)6 HashMap (java.util.HashMap)6 Map (java.util.Map)6 BlockingQueue (java.util.concurrent.BlockingQueue)6 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)6