Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Transaction] Transaction pending ack persistent #8881

Conversation

congbobo184
Copy link
Contributor

@congbobo184 congbobo184 commented Dec 9, 2020

Motivation

in order to handle pending ack persistent.

implement

  1. add the transaction pending ack store, it will handle the pending ack metadata store.
  2. when the sub unload, we will replay the pendingAckHandle.
  3. we use one manageLedger to store the pending ack metadata by one sub , and replay by this managedLedger open cursor.
  4. when we commit or abort the transaction, we will append the marker to the pendingAckStore then we will modify state memory in pendingAckHandle
  5. we also modify the in memory state when append fail, because we don't know the persistent state, when we replay it, it will produce the wrong operation. so we append fail, we should wait tc time out or client abort this transaction.
  6. when we append pending ack log, we will compare the the log position store the biggest topic position is bigger than persistent topic markDeletePosition. if it is smaller, will delete the position.

Verifying this change

Add the tests for it

Does this pull request potentially affect one of the following parts:
If yes was chosen, please highlight the changes

Dependencies (does it add or upgrade a dependency): (no)
The public API: (no)
The schema: (no)
The default values of configurations: (no)
The wire protocol: (no)
The rest endpoints: (no)
The admin cli options: (no)
Anything that affects deployment: (no)

congbo added 3 commits December 9, 2020 19:08
…tion_pendingack_persistent

# Conflicts:
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckHandle.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/PendingAckHandleImpl.java
Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a great work.
I believe this is a fundamental implementation in order to ship Transactions to the users



PROTOC=${PROTOC:-protoc}
${PROTOC} --java_out=pulsar-broker/src/main/java pulsar-broker/src/main/proto/TransactionPendingAck.proto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this file ?

docker pull $IMAGE

WORKDIR=/workdir
docker run -i \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this file ?

@@ -161,6 +162,12 @@ void setReplicated(boolean replicated) {

@Override
public synchronized void addConsumer(Consumer consumer) throws BrokerServiceException {
if (pendingAckHandle instanceof PendingAckHandleImpl) {
if (!((PendingAckHandleImpl) pendingAckHandle).checkIfReady()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add checkIdReady to PendingAckHandle ?
using instanceof is not a good practice, we should leverage polymorphism

try {
Thread.sleep(1);
} catch (InterruptedException e) {
//no-op
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not good,
the contract is to exit the current activity in case of InterrupedException or at least set Thread.interrupted flag

InitialPosition.Earliest, new AsyncCallbacks.OpenCursorCallback() {
@Override
public void openCursorComplete(ManagedCursor cursor, Object ctx) {
if (timer == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about creating a method in parent class MLPendingAckStoreProvider

void ensureTimer() {
     if (timer == null) {
         synchronized(this) {
             initialize();  
       }
    }
}

IMHO code will be more readable

this.timer.newTimeout(this, intervalTime, TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error("PendingAck timer task error!", e);
if ("Cursor was already closed".equals(e.getCause().getMessage())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very error prone,
can we detect an instance of a specific class of exception ?

congbo added 8 commits February 7, 2021 12:05
…tion_pendingack_persistent

# Conflicts:
#	pom.xml
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/service/TransactionMarkerDeleteTest.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/service/persistent/PersistentSubscriptionTest.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/transaction/TransactionTestBase.java
…://github.com/congbobo184/pulsar into congbobo184_transaction_pendingack_persistent

# Conflicts:
#	pom.xml
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentSubscription.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckHandle.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckReplyCallBack.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckStore.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/TransactionPendingAckStoreProvider.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/InMemoryPendingAckStore.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/MLPendingAckReplyCallBack.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/MLPendingAckStore.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/MLPendingAckStoreProvider.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/MLPendingAckStoreTimerTask.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/PendingAckHandleDisabled.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/PendingAckHandleImpl.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/service/TransactionMarkerDeleteTest.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/service/persistent/PersistentSubscriptionTest.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/transaction/TransactionTestBase.java
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckPersistentTest.java
@codelipenghui codelipenghui added this to the 2.8.0 milestone Mar 2, 2021
# Conflicts:
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckHandle.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/transaction/pendingack/impl/PendingAckHandleImpl.java
@codelipenghui
Copy link
Contributor

@gaoran10 Please help review this PR.

@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

1 similar comment
@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

congbo added 9 commits March 17, 2021 19:02
# Conflicts:
#	pulsar-broker/src/test/java/org/apache/pulsar/broker/transaction/pendingack/PendingAckInMemoryDeleteTest.java
delete pending ack recover exception
# Conflicts:
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
# Conflicts:
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractTopic.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentTopic.java
#	pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java
@congbobo184
Copy link
Contributor Author

@codelipenghui @eolivelli please review again. thanks.

Comment on lines +274 to +283
} catch (BrokerServiceException e) {
if (e instanceof ConsumerBusyException) {
log.warn("[{}][{}] Consumer {} {} already connected", topic, subscriptionName, consumerId,
consumerName);
} else if (e instanceof SubscriptionBusyException) {
log.warn("[{}][{}] {}", topic, subscriptionName, e.getMessage());
}

decrementUsageCount();
future.completeExceptionally(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to catch the exception here? If the exception occurs, you already have .exceptionally to deal with this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the close is Is a synchronous method, so we should catch the exception.

} catch (BrokerServiceException e) {
if (e instanceof ConsumerBusyException) {
}).exceptionally(e -> {
if (e.getCause() instanceof ConsumerBusyException) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to get the Cause first and use it in the followings.


public static final String PENDING_ACK_STORE_SUFFIX = "__transaction_pendingack";

private static final String PENDING_ACK_STORE_CURSOR_NAME = "pendingack";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static final String PENDING_ACK_STORE_CURSOR_NAME = "pendingack";
private static final String PENDING_ACK_STORE_CURSOR_NAME = "__pending_ack_state";


private final ManagedCursor cursor;

public static final String PENDING_ACK_STORE_SUFFIX = "__transaction_pendingack";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static final String PENDING_ACK_STORE_SUFFIX = "__transaction_pendingack";
public static final String PENDING_ACK_STORE_SUFFIX = "__transaction_pending_ack";

@codelipenghui codelipenghui merged commit 8f1f5ba into apache:master May 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants