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

[fix][txn] Use correct tcId variable to prevent data race #8

Closed
wants to merge 5 commits into from

Conversation

michaeljmarshall
Copy link
Owner

PR for test validation

michaeljmarshall added a commit to apache/pulsar that referenced this pull request Dec 20, 2022
…rCnx (#18987)

### Motivation

In the `PulsarDecoder`, we use a single `BaseCommand` object and overwrite it for each incoming protocol message. As a result, it is not safe to publish any references to a proto command to other threads.

Here is the single `BaseCommand`:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L99

Here is the method call that resets the object:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L114

Note that the call to `parseFrom` first calls `clear()`, which resets all values on the object.

This PR copies relevant values or objects into other variables.

### Modifications

* Replace `command` with `tcId` since the latter is a final variable meant to be published to another thread.
* Move logic to copy certain command fields to earlier in method for `handleSubscribe`
* Copy `ack` object to new `CommandAck` when there is a broker interceptor. Note that copying this command is likely somewhat costly, so we only do it when there is an interceptor configured.

### Verifying this change

This is a trivial change that is already covered by tests.

### Documentation

- [x] `doc-not-needed` 

This is an internal change.

### Matching PR in forked repository

PR in forked repository: michaeljmarshall#8
michaeljmarshall added a commit to apache/pulsar that referenced this pull request Dec 21, 2022
…rCnx (#18987)

In the `PulsarDecoder`, we use a single `BaseCommand` object and overwrite it for each incoming protocol message. As a result, it is not safe to publish any references to a proto command to other threads.

Here is the single `BaseCommand`:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L99

Here is the method call that resets the object:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L114

Note that the call to `parseFrom` first calls `clear()`, which resets all values on the object.

This PR copies relevant values or objects into other variables.

* Replace `command` with `tcId` since the latter is a final variable meant to be published to another thread.
* Move logic to copy certain command fields to earlier in method for `handleSubscribe`
* Copy `ack` object to new `CommandAck` when there is a broker interceptor. Note that copying this command is likely somewhat costly, so we only do it when there is an interceptor configured.

This is a trivial change that is already covered by tests.

- [x] `doc-not-needed`

This is an internal change.

PR in forked repository: michaeljmarshall#8

(cherry picked from commit a408e9e)
michaeljmarshall added a commit to apache/pulsar that referenced this pull request Dec 21, 2022
…rCnx (#18987)

In the `PulsarDecoder`, we use a single `BaseCommand` object and overwrite it for each incoming protocol message. As a result, it is not safe to publish any references to a proto command to other threads.

Here is the single `BaseCommand`:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L99

Here is the method call that resets the object:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L114

Note that the call to `parseFrom` first calls `clear()`, which resets all values on the object.

This PR copies relevant values or objects into other variables.

* Replace `command` with `tcId` since the latter is a final variable meant to be published to another thread.
* Move logic to copy certain command fields to earlier in method for `handleSubscribe`
* Copy `ack` object to new `CommandAck` when there is a broker interceptor. Note that copying this command is likely somewhat costly, so we only do it when there is an interceptor configured.

This is a trivial change that is already covered by tests.

- [x] `doc-not-needed`

This is an internal change.

PR in forked repository: michaeljmarshall#8

(cherry picked from commit a408e9e)
michaeljmarshall added a commit to apache/pulsar that referenced this pull request Dec 21, 2022
…rCnx (#18987)

In the `PulsarDecoder`, we use a single `BaseCommand` object and overwrite it for each incoming protocol message. As a result, it is not safe to publish any references to a proto command to other threads.

Here is the single `BaseCommand`:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L99

Here is the method call that resets the object:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L114

Note that the call to `parseFrom` first calls `clear()`, which resets all values on the object.

This PR copies relevant values or objects into other variables.

* Replace `command` with `tcId` since the latter is a final variable meant to be published to another thread.
* Move logic to copy certain command fields to earlier in method for `handleSubscribe`
* Copy `ack` object to new `CommandAck` when there is a broker interceptor. Note that copying this command is likely somewhat costly, so we only do it when there is an interceptor configured.

This is a trivial change that is already covered by tests.

- [x] `doc-not-needed`

This is an internal change.

PR in forked repository: michaeljmarshall#8

(cherry picked from commit a408e9e)
michaeljmarshall added a commit to datastax/pulsar that referenced this pull request Dec 21, 2022
…rCnx (apache#18987)

In the `PulsarDecoder`, we use a single `BaseCommand` object and overwrite it for each incoming protocol message. As a result, it is not safe to publish any references to a proto command to other threads.

Here is the single `BaseCommand`:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L99

Here is the method call that resets the object:

https://github.com/apache/pulsar/blob/82237d3684fe506bcb6426b3b23f413422e6e4fb/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java#L114

Note that the call to `parseFrom` first calls `clear()`, which resets all values on the object.

This PR copies relevant values or objects into other variables.

* Replace `command` with `tcId` since the latter is a final variable meant to be published to another thread.
* Move logic to copy certain command fields to earlier in method for `handleSubscribe`
* Copy `ack` object to new `CommandAck` when there is a broker interceptor. Note that copying this command is likely somewhat costly, so we only do it when there is an interceptor configured.

This is a trivial change that is already covered by tests.

- [x] `doc-not-needed`

This is an internal change.

PR in forked repository: michaeljmarshall#8

(cherry picked from commit a408e9e)
@github-actions
Copy link

The pr had no activity for 30 days, mark with Stale label.

@github-actions github-actions bot added the Stale label Jan 19, 2023
@michaeljmarshall michaeljmarshall deleted the use-final-variable branch January 23, 2023 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant