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);
}
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());
}
}
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);
}
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;
}
Aggregations