Search in sources :

Example 1 with PendingAckMetadata

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

the class MLPendingAckStore method appendCumulativeAck.

@Override
public CompletableFuture<Void> appendCumulativeAck(TxnID txnID, PositionImpl position) {
    PendingAckMetadataEntry pendingAckMetadataEntry = new PendingAckMetadataEntry();
    pendingAckMetadataEntry.setPendingAckOp(PendingAckOp.ACK);
    pendingAckMetadataEntry.setAckType(AckType.Cumulative);
    PendingAckMetadata pendingAckMetadata = new PendingAckMetadata();
    if (position.getAckSet() != null) {
        for (long l : position.getAckSet()) {
            pendingAckMetadata.addAckSet(l);
        }
    }
    pendingAckMetadata.setLedgerId(position.getLedgerId());
    pendingAckMetadata.setEntryId(position.getEntryId());
    pendingAckMetadataEntry.addAllPendingAckMetadatas(Collections.singleton(pendingAckMetadata));
    return appendCommon(pendingAckMetadataEntry, txnID);
}
Also used : PendingAckMetadata(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadata) PendingAckMetadataEntry(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadataEntry)

Example 2 with PendingAckMetadata

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

the class MLPendingAckReplyCallBack method handleMetadataEntry.

@Override
public void handleMetadataEntry(PendingAckMetadataEntry pendingAckMetadataEntry) {
    TxnID txnID = new TxnID(pendingAckMetadataEntry.getTxnidMostBits(), pendingAckMetadataEntry.getTxnidLeastBits());
    AckType ackType = pendingAckMetadataEntry.getAckType();
    switch(pendingAckMetadataEntry.getPendingAckOp()) {
        case ABORT:
            pendingAckHandle.handleAbort(txnID, ackType);
            break;
        case COMMIT:
            pendingAckHandle.handleCommit(txnID, ackType, Collections.emptyMap());
            break;
        case ACK:
            if (ackType == AckType.Cumulative) {
                PendingAckMetadata pendingAckMetadata = pendingAckMetadataEntry.getPendingAckMetadatasList().get(0);
                pendingAckHandle.handleCumulativeAckRecover(txnID, PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId()));
            } else {
                List<MutablePair<PositionImpl, Integer>> positions = new ArrayList<>();
                pendingAckMetadataEntry.getPendingAckMetadatasList().forEach(pendingAckMetadata -> {
                    if (pendingAckMetadata.getAckSetsCount() == 0) {
                        positions.add(new MutablePair<>(PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId()), pendingAckMetadata.getBatchSize()));
                    } else {
                        PositionImpl position = PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId());
                        if (pendingAckMetadata.getAckSetsCount() > 0) {
                            long[] ackSets = new long[pendingAckMetadata.getAckSetsCount()];
                            for (int i = 0; i < pendingAckMetadata.getAckSetsCount(); i++) {
                                ackSets[i] = pendingAckMetadata.getAckSetAt(i);
                            }
                            position.setAckSet(ackSets);
                        }
                        positions.add(new MutablePair<>(position, pendingAckMetadata.getBatchSize()));
                    }
                });
                pendingAckHandle.handleIndividualAckRecover(txnID, positions);
            }
            break;
        default:
            throw new IllegalStateException("Transaction pending ack replay " + "error with illegal state : " + pendingAckMetadataEntry.getPendingAckOp());
    }
}
Also used : MutablePair(org.apache.commons.lang3.tuple.MutablePair) TxnID(org.apache.pulsar.client.api.transaction.TxnID) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) PendingAckMetadata(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadata) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) ArrayList(java.util.ArrayList)

Example 3 with PendingAckMetadata

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

the class MLPendingAckStore method appendIndividualAck.

@Override
public CompletableFuture<Void> appendIndividualAck(TxnID txnID, List<MutablePair<PositionImpl, Integer>> positions) {
    PendingAckMetadataEntry pendingAckMetadataEntry = new PendingAckMetadataEntry();
    pendingAckMetadataEntry.setPendingAckOp(PendingAckOp.ACK);
    pendingAckMetadataEntry.setAckType(AckType.Individual);
    List<PendingAckMetadata> pendingAckMetadataList = new ArrayList<>();
    positions.forEach(positionIntegerMutablePair -> {
        PendingAckMetadata pendingAckMetadata = new PendingAckMetadata();
        PositionImpl position = positionIntegerMutablePair.getLeft();
        int batchSize = positionIntegerMutablePair.getRight();
        if (positionIntegerMutablePair.getLeft().getAckSet() != null) {
            for (long l : position.getAckSet()) {
                pendingAckMetadata.addAckSet(l);
            }
        }
        pendingAckMetadata.setLedgerId(position.getLedgerId());
        pendingAckMetadata.setEntryId(position.getEntryId());
        pendingAckMetadata.setBatchSize(batchSize);
        pendingAckMetadataList.add(pendingAckMetadata);
    });
    pendingAckMetadataEntry.addAllPendingAckMetadatas(pendingAckMetadataList);
    return appendCommon(pendingAckMetadataEntry, txnID);
}
Also used : PendingAckMetadata(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadata) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) ArrayList(java.util.ArrayList) PendingAckMetadataEntry(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadataEntry)

Example 4 with PendingAckMetadata

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

the class MLPendingAckStore method appendCommon.

private CompletableFuture<Void> appendCommon(PendingAckMetadataEntry pendingAckMetadataEntry, TxnID txnID) {
    CompletableFuture<Void> completableFuture = new CompletableFuture<>();
    pendingAckMetadataEntry.setTxnidLeastBits(txnID.getLeastSigBits());
    pendingAckMetadataEntry.setTxnidMostBits(txnID.getMostSigBits());
    int transactionMetadataEntrySize = pendingAckMetadataEntry.getSerializedSize();
    ByteBuf buf = PulsarByteBufAllocator.DEFAULT.buffer(transactionMetadataEntrySize, transactionMetadataEntrySize);
    pendingAckMetadataEntry.writeTo(buf);
    managedLedger.asyncAddEntry(buf, new AsyncCallbacks.AddEntryCallback() {

        @Override
        public void addComplete(Position position, ByteBuf entryData, Object ctx) {
            if (log.isDebugEnabled()) {
                log.debug("[{}][{}] MLPendingAckStore message append success at {} txnId: {}, operation : {}", managedLedger.getName(), ctx, position, txnID, pendingAckMetadataEntry.getPendingAckOp());
            }
            // store the persistent position in to memory
            if (pendingAckMetadataEntry.getPendingAckOp() != PendingAckOp.ABORT && pendingAckMetadataEntry.getPendingAckOp() != PendingAckOp.COMMIT) {
                Optional<PendingAckMetadata> optional = pendingAckMetadataEntry.getPendingAckMetadatasList().stream().max((o1, o2) -> ComparisonChain.start().compare(o1.getLedgerId(), o2.getLedgerId()).compare(o1.getEntryId(), o2.getEntryId()).result());
                optional.ifPresent(pendingAckMetadata -> metadataPositions.compute((PositionImpl) position, (thisPosition, otherPosition) -> {
                    PositionImpl nowPosition = PositionImpl.get(pendingAckMetadata.getLedgerId(), pendingAckMetadata.getEntryId());
                    if (otherPosition == null) {
                        return nowPosition;
                    } else {
                        return nowPosition.compareTo(otherPosition) > 0 ? nowPosition : otherPosition;
                    }
                }));
            }
            buf.release();
            completableFuture.complete(null);
            if (!metadataPositions.isEmpty()) {
                PositionImpl firstPosition = metadataPositions.firstEntry().getKey();
                PositionImpl deletePosition = metadataPositions.firstEntry().getKey();
                while (!metadataPositions.isEmpty() && metadataPositions.firstKey() != null && subManagedCursor.getPersistentMarkDeletedPosition() != null && metadataPositions.firstEntry().getValue().compareTo((PositionImpl) subManagedCursor.getPersistentMarkDeletedPosition()) <= 0) {
                    deletePosition = metadataPositions.firstKey();
                    metadataPositions.remove(metadataPositions.firstKey());
                }
                if (firstPosition != deletePosition) {
                    PositionImpl finalDeletePosition = deletePosition;
                    cursor.asyncMarkDelete(deletePosition, new AsyncCallbacks.MarkDeleteCallback() {

                        @Override
                        public void markDeleteComplete(Object ctx) {
                            if (log.isDebugEnabled()) {
                                log.debug("[{}] Transaction pending ack store mark delete position : " + "[{}] success", managedLedger.getName(), finalDeletePosition);
                            }
                        }

                        @Override
                        public void markDeleteFailed(ManagedLedgerException exception, Object ctx) {
                            if (log.isDebugEnabled()) {
                                log.error("[{}] Transaction pending ack store mark delete position : " + "[{}] fail!", managedLedger.getName(), finalDeletePosition, exception);
                            }
                        }
                    }, null);
                }
            }
        }

        @Override
        public void addFailed(ManagedLedgerException exception, Object ctx) {
            log.error("[{}][{}] MLPendingAckStore message append fail exception : {}, operation : {}", managedLedger.getName(), ctx, exception, pendingAckMetadataEntry.getPendingAckOp());
            buf.release();
            completableFuture.completeExceptionally(new PersistenceException(exception));
        }
    }, null);
    return completableFuture;
}
Also used : SpscArrayQueue(org.jctools.queues.SpscArrayQueue) TopicName(org.apache.pulsar.common.naming.TopicName) AckType(org.apache.pulsar.common.api.proto.CommandAck.AckType) Entry(org.apache.bookkeeper.mledger.Entry) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) PendingAckOp(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckOp) PendingAckMetadata(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadata) ArrayList(java.util.ArrayList) TxnID(org.apache.pulsar.client.api.transaction.TxnID) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) ByteBuf(io.netty.buffer.ByteBuf) MutablePair(org.apache.commons.lang3.tuple.MutablePair) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) Logger(org.slf4j.Logger) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) PendingAckReplyCallBack(org.apache.pulsar.broker.transaction.pendingack.PendingAckReplyCallBack) Position(org.apache.bookkeeper.mledger.Position) ComparisonChain(com.google.common.collect.ComparisonChain) PulsarByteBufAllocator(org.apache.pulsar.common.allocator.PulsarByteBufAllocator) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) MessagePassingQueue(org.jctools.queues.MessagePassingQueue) Optional(java.util.Optional) PendingAckStore(org.apache.pulsar.broker.transaction.pendingack.PendingAckStore) PendingAckMetadataEntry(org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadataEntry) Collections(java.util.Collections) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks) Optional(java.util.Optional) Position(org.apache.bookkeeper.mledger.Position) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) ByteBuf(io.netty.buffer.ByteBuf) CompletableFuture(java.util.concurrent.CompletableFuture) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistenceException(org.apache.pulsar.broker.service.BrokerServiceException.PersistenceException) AsyncCallbacks(org.apache.bookkeeper.mledger.AsyncCallbacks)

Aggregations

PendingAckMetadata (org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadata)4 ArrayList (java.util.ArrayList)3 PositionImpl (org.apache.bookkeeper.mledger.impl.PositionImpl)3 PendingAckMetadataEntry (org.apache.pulsar.broker.transaction.pendingack.proto.PendingAckMetadataEntry)3 MutablePair (org.apache.commons.lang3.tuple.MutablePair)2 TxnID (org.apache.pulsar.client.api.transaction.TxnID)2 AckType (org.apache.pulsar.common.api.proto.CommandAck.AckType)2 ComparisonChain (com.google.common.collect.ComparisonChain)1 ByteBuf (io.netty.buffer.ByteBuf)1 Collections (java.util.Collections)1 List (java.util.List)1 Optional (java.util.Optional)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AsyncCallbacks (org.apache.bookkeeper.mledger.AsyncCallbacks)1 Entry (org.apache.bookkeeper.mledger.Entry)1 ManagedCursor (org.apache.bookkeeper.mledger.ManagedCursor)1 ManagedLedger (org.apache.bookkeeper.mledger.ManagedLedger)1