use of org.apache.pulsar.transaction.coordinator.TxnMeta in project pulsar by apache.
the class TransactionsBase method internalGetSlowTransactions.
protected void internalGetSlowTransactions(AsyncResponse asyncResponse, boolean authoritative, long timeout, Integer coordinatorId) {
try {
if (pulsar().getConfig().isTransactionCoordinatorEnabled()) {
if (coordinatorId != null) {
validateTopicOwnership(TopicName.TRANSACTION_COORDINATOR_ASSIGN.getPartition(coordinatorId), authoritative);
TransactionMetadataStore transactionMetadataStore = pulsar().getTransactionMetadataStoreService().getStores().get(TransactionCoordinatorID.get(coordinatorId));
if (transactionMetadataStore == null) {
asyncResponse.resume(new RestException(NOT_FOUND, "Transaction coordinator not found! coordinator id : " + coordinatorId));
return;
}
List<TxnMeta> transactions = transactionMetadataStore.getSlowTransactions(timeout);
List<CompletableFuture<TransactionMetadata>> completableFutures = new ArrayList<>();
for (TxnMeta txnMeta : transactions) {
CompletableFuture<TransactionMetadata> completableFuture = new CompletableFuture<>();
getTransactionMetadata(txnMeta, completableFuture);
completableFutures.add(completableFuture);
}
FutureUtil.waitForAll(completableFutures).whenComplete((v, e) -> {
if (e != null) {
asyncResponse.resume(new RestException(e.getCause()));
return;
}
Map<String, TransactionMetadata> transactionMetadata = new HashMap<>();
for (CompletableFuture<TransactionMetadata> future : completableFutures) {
try {
transactionMetadata.put(future.get().txnId, future.get());
} catch (Exception exception) {
asyncResponse.resume(new RestException(exception.getCause()));
return;
}
}
asyncResponse.resume(transactionMetadata);
});
} else {
getPartitionedTopicMetadataAsync(TopicName.TRANSACTION_COORDINATOR_ASSIGN, false, false).thenAccept(partitionMetadata -> {
if (partitionMetadata.partitions == 0) {
asyncResponse.resume(new RestException(Response.Status.NOT_FOUND, "Transaction coordinator not found"));
return;
}
List<CompletableFuture<Map<String, TransactionMetadata>>> completableFutures = Lists.newArrayList();
for (int i = 0; i < partitionMetadata.partitions; i++) {
try {
completableFutures.add(pulsar().getAdminClient().transactions().getSlowTransactionsByCoordinatorIdAsync(i, timeout, TimeUnit.MILLISECONDS));
} catch (PulsarServerException e) {
asyncResponse.resume(new RestException(e));
return;
}
}
Map<String, TransactionMetadata> transactionMetadataMaps = new HashMap<>();
FutureUtil.waitForAll(completableFutures).whenComplete((result, e) -> {
if (e != null) {
asyncResponse.resume(new RestException(e));
return;
}
for (CompletableFuture<Map<String, TransactionMetadata>> transactionMetadataMap : completableFutures) {
try {
transactionMetadataMaps.putAll(transactionMetadataMap.get());
} catch (Exception exception) {
asyncResponse.resume(new RestException(exception.getCause()));
return;
}
}
asyncResponse.resume(transactionMetadataMaps);
});
}).exceptionally(ex -> {
log.error("[{}] Failed to get transaction coordinator state.", clientAppId(), ex);
resumeAsyncResponseExceptionally(asyncResponse, ex);
return null;
});
}
} else {
asyncResponse.resume(new RestException(SERVICE_UNAVAILABLE, "Broker don't support transaction!"));
}
} catch (Exception e) {
asyncResponse.resume(new RestException(e));
}
}
use of org.apache.pulsar.transaction.coordinator.TxnMeta in project pulsar by apache.
the class TransactionMetadataStoreServiceTest method testTimeoutTrackerMultiThreading.
@Test
public void testTimeoutTrackerMultiThreading() throws Exception {
pulsar.getTransactionMetadataStoreService().handleTcClientConnect(TransactionCoordinatorID.get(0));
Awaitility.await().until(() -> pulsar.getTransactionMetadataStoreService().getStores().get(TransactionCoordinatorID.get(0)) != null);
MLTransactionMetadataStore transactionMetadataStore = (MLTransactionMetadataStore) pulsar.getTransactionMetadataStoreService().getStores().get(TransactionCoordinatorID.get(0));
checkTransactionMetadataStoreReady(transactionMetadataStore);
Field field = MLTransactionMetadataStore.class.getDeclaredField("txnMetaMap");
field.setAccessible(true);
ConcurrentSkipListMap<Long, Pair<TxnMeta, List<Position>>> txnMap = (ConcurrentSkipListMap<Long, Pair<TxnMeta, List<Position>>>) field.get(transactionMetadataStore);
new Thread(() -> {
int i = -1;
while (++i < 100) {
try {
transactionMetadataStore.newTransaction(1000);
} catch (Exception e) {
// no operation
}
}
}).start();
new Thread(() -> {
int i = -1;
while (++i < 100) {
try {
transactionMetadataStore.newTransaction(2000);
} catch (Exception e) {
// no operation
}
}
}).start();
new Thread(() -> {
int i = -1;
while (++i < 100) {
try {
transactionMetadataStore.newTransaction(3000);
} catch (Exception e) {
// no operation
}
}
}).start();
new Thread(() -> {
int i = -1;
while (++i < 100) {
try {
transactionMetadataStore.newTransaction(4000);
} catch (Exception e) {
// no operation
}
}
}).start();
checkoutTimeout(txnMap, 300);
checkoutTimeout(txnMap, 200);
checkoutTimeout(txnMap, 100);
checkoutTimeout(txnMap, 0);
}
use of org.apache.pulsar.transaction.coordinator.TxnMeta in project pulsar by apache.
the class TransactionMetadataStoreServiceTest method testAddAckedPartitionToTxn.
@Test
public void testAddAckedPartitionToTxn() throws Exception {
TransactionMetadataStoreService transactionMetadataStoreService = pulsar.getTransactionMetadataStoreService();
transactionMetadataStoreService.handleTcClientConnect(TransactionCoordinatorID.get(0)).get();
Awaitility.await().until(() -> transactionMetadataStoreService.getStores().size() == 1);
MLTransactionMetadataStore transactionMetadataStore = (MLTransactionMetadataStore) pulsar.getTransactionMetadataStoreService().getStores().get(TransactionCoordinatorID.get(0));
checkTransactionMetadataStoreReady(transactionMetadataStore);
TxnID txnID = transactionMetadataStoreService.newTransaction(TransactionCoordinatorID.get(0), 5000).get();
List<TransactionSubscription> partitions = new ArrayList<>();
partitions.add(TransactionSubscription.builder().topic("ptn-1").subscription("sub-1").build());
partitions.add(TransactionSubscription.builder().topic("ptn-2").subscription("sub-1").build());
partitions.add(TransactionSubscription.builder().topic("ptn-3").subscription("sub-1").build());
transactionMetadataStoreService.addAckedPartitionToTxn(txnID, partitions);
TxnMeta txn = transactionMetadataStoreService.getTxnMeta(txnID).get();
assertEquals(txn.status(), TxnStatus.OPEN);
transactionMetadataStoreService.removeTransactionMetadataStore(TransactionCoordinatorID.get(0));
Assert.assertEquals(transactionMetadataStoreService.getStores().size(), 0);
}
use of org.apache.pulsar.transaction.coordinator.TxnMeta in project pulsar by apache.
the class InMemTransactionMetadataStore method getTxnMeta.
@Override
public CompletableFuture<TxnMeta> getTxnMeta(TxnID txnid) {
CompletableFuture<TxnMeta> getFuture = new CompletableFuture<>();
TxnMetaImpl txn = transactions.get(txnid);
if (null == txn) {
getFuture.completeExceptionally(new TransactionNotFoundException(txnid));
} else {
getFuture.complete(txn);
}
return getFuture;
}
use of org.apache.pulsar.transaction.coordinator.TxnMeta in project pulsar by apache.
the class MLTransactionMetadataStore method newTransaction.
@Override
public CompletableFuture<TxnID> newTransaction(long timeOut) {
CompletableFuture<TxnID> completableFuture = new CompletableFuture<>();
internalPinnedExecutor.execute(() -> {
if (!checkIfReady()) {
completableFuture.completeExceptionally(new CoordinatorException.TransactionMetadataStoreStateException(tcID, State.Ready, getState(), "new Transaction"));
return;
}
long mostSigBits = tcID.getId();
long leastSigBits = sequenceIdGenerator.generateSequenceId();
TxnID txnID = new TxnID(mostSigBits, leastSigBits);
long currentTimeMillis = System.currentTimeMillis();
TransactionMetadataEntry transactionMetadataEntry = new TransactionMetadataEntry().setTxnidMostBits(mostSigBits).setTxnidLeastBits(leastSigBits).setStartTime(currentTimeMillis).setTimeoutMs(timeOut).setMetadataOp(TransactionMetadataEntry.TransactionMetadataOp.NEW).setLastModificationTime(currentTimeMillis).setMaxLocalTxnId(sequenceIdGenerator.getCurrentSequenceId());
transactionLog.append(transactionMetadataEntry).whenComplete((position, throwable) -> {
if (throwable != null) {
completableFuture.completeExceptionally(throwable);
} else {
appendLogCount.increment();
TxnMeta txn = new TxnMetaImpl(txnID, currentTimeMillis, timeOut);
List<Position> positions = new ArrayList<>();
positions.add(position);
Pair<TxnMeta, List<Position>> pair = MutablePair.of(txn, positions);
txnMetaMap.put(leastSigBits, pair);
this.timeoutTracker.addTransaction(leastSigBits, timeOut);
createdTransactionCount.increment();
completableFuture.complete(txnID);
}
});
});
return completableFuture;
}
Aggregations