Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

Conversation

@BewareMyPower
Copy link
Collaborator

@BewareMyPower BewareMyPower commented Feb 2, 2022

NOTE: This PR introduced a memory leak that was first introduced in release 2.8.2.6, 2.9.2.2. And will be fixed by #1069.


Motivation

There is a thread safety issue for MessageFetchContext. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

Thread name Method name
pulsar-io-18-12 MessageFetchContext
pulsar-io-18-12 handleFetch
pulsar-io-18-12 handlePartitionData
pulsar-io-18-12 checkOffsetOutOfRange
BookKeeperClientWorker-OrderedExecutor-10-0 readEntries
BookKeeperClientWorker-OrderedExecutor-10-0 handleEntries
metadata-store-19-1 tryComplete
metadata-store-19-1 complete
metadata-store-19-1 recycle

Though all fields are never modified before recycle() is called, the visibility of these fields cannot be guaranteed without volatile.

Modifications

  • Add volatile keyword to fields of MessageFetchContext except the atomic variables and thread safe containers.
  • For atomic variables and thread safe containers, make them final and initialize them in the constructor. In recycle() method, instead of resetting them with null values, just reset them to the default state.

This PR can also improve the performance. Because even if MessageFetchContext is managed by the Netty object pool, each time it's allocated from MessageFetchContext#get, the atomic variables and thread safe containers are still allocated from heap memory.

@Demogorgon314 Demogorgon314 merged commit 0f1f826 into streamnative:master Feb 3, 2022
@BewareMyPower BewareMyPower deleted the bewaremypower/thread-safe-fetch-context branch February 3, 2022 10:53
BewareMyPower added a commit that referenced this pull request Feb 3, 2022
### Motivation

There is a thread safety issue for `MessageFetchContext`. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

| Thread name                                 | Method name             |
| ------------------------------------------- | ----------------------- |
| pulsar-io-18-12                             | `MessageFetchContext`   |
| pulsar-io-18-12                             | `handleFetch`           |
| pulsar-io-18-12                             | `handlePartitionData`   |
| pulsar-io-18-12                             | `checkOffsetOutOfRange` |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `readEntries`           |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `handleEntries`         |
| metadata-store-19-1                         | `tryComplete`           |
| metadata-store-19-1                         | `complete`              |
| metadata-store-19-1                         | `recycle`               |

Though all fields are never modified before `recycle()` is called, the visibility of these fields cannot be guaranteed without `volatile`.

### Modifications
- Add `volatile` keyword to fields of `MessageFetchContext` except the atomic variables and thread safe containers.
- For atomic variables and thread safe containers, make them `final` and initialize them in the constructor. In `recycle()` method, instead of resetting them with `null` values, just reset them to the default state.

This PR can also improve the performance. Because even if `MessageFetchContext` is managed by the Netty object pool, each time it's allocated from `MessageFetchContext#get`, the atomic variables and thread safe containers are still allocated from heap memory.
BewareMyPower added a commit that referenced this pull request Feb 3, 2022
### Motivation

There is a thread safety issue for `MessageFetchContext`. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

| Thread name                                 | Method name             |
| ------------------------------------------- | ----------------------- |
| pulsar-io-18-12                             | `MessageFetchContext`   |
| pulsar-io-18-12                             | `handleFetch`           |
| pulsar-io-18-12                             | `handlePartitionData`   |
| pulsar-io-18-12                             | `checkOffsetOutOfRange` |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `readEntries`           |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `handleEntries`         |
| metadata-store-19-1                         | `tryComplete`           |
| metadata-store-19-1                         | `complete`              |
| metadata-store-19-1                         | `recycle`               |

Though all fields are never modified before `recycle()` is called, the visibility of these fields cannot be guaranteed without `volatile`.

### Modifications
- Add `volatile` keyword to fields of `MessageFetchContext` except the atomic variables and thread safe containers.
- For atomic variables and thread safe containers, make them `final` and initialize them in the constructor. In `recycle()` method, instead of resetting them with `null` values, just reset them to the default state.

This PR can also improve the performance. Because even if `MessageFetchContext` is managed by the Netty object pool, each time it's allocated from `MessageFetchContext#get`, the atomic variables and thread safe containers are still allocated from heap memory.

(cherry picked from commit 0f1f826)
BewareMyPower added a commit that referenced this pull request Feb 3, 2022
### Motivation

There is a thread safety issue for `MessageFetchContext`. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

| Thread name                                 | Method name             |
| ------------------------------------------- | ----------------------- |
| pulsar-io-18-12                             | `MessageFetchContext`   |
| pulsar-io-18-12                             | `handleFetch`           |
| pulsar-io-18-12                             | `handlePartitionData`   |
| pulsar-io-18-12                             | `checkOffsetOutOfRange` |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `readEntries`           |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `handleEntries`         |
| metadata-store-19-1                         | `tryComplete`           |
| metadata-store-19-1                         | `complete`              |
| metadata-store-19-1                         | `recycle`               |

Though all fields are never modified before `recycle()` is called, the visibility of these fields cannot be guaranteed without `volatile`.

### Modifications
- Add `volatile` keyword to fields of `MessageFetchContext` except the atomic variables and thread safe containers.
- For atomic variables and thread safe containers, make them `final` and initialize them in the constructor. In `recycle()` method, instead of resetting them with `null` values, just reset them to the default state.

This PR can also improve the performance. Because even if `MessageFetchContext` is managed by the Netty object pool, each time it's allocated from `MessageFetchContext#get`, the atomic variables and thread safe containers are still allocated from heap memory.

(cherry picked from commit 0f1f826)
BewareMyPower added a commit that referenced this pull request Feb 9, 2022
### Motivation

There is a thread safety issue for `MessageFetchContext`. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

| Thread name                                 | Method name             |
| ------------------------------------------- | ----------------------- |
| pulsar-io-18-12                             | `MessageFetchContext`   |
| pulsar-io-18-12                             | `handleFetch`           |
| pulsar-io-18-12                             | `handlePartitionData`   |
| pulsar-io-18-12                             | `checkOffsetOutOfRange` |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `readEntries`           |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `handleEntries`         |
| metadata-store-19-1                         | `tryComplete`           |
| metadata-store-19-1                         | `complete`              |
| metadata-store-19-1                         | `recycle`               |

Though all fields are never modified before `recycle()` is called, the visibility of these fields cannot be guaranteed without `volatile`.

### Modifications
- Add `volatile` keyword to fields of `MessageFetchContext` except the atomic variables and thread safe containers.
- For atomic variables and thread safe containers, make them `final` and initialize them in the constructor. In `recycle()` method, instead of resetting them with `null` values, just reset them to the default state.

This PR can also improve the performance. Because even if `MessageFetchContext` is managed by the Netty object pool, each time it's allocated from `MessageFetchContext#get`, the atomic variables and thread safe containers are still allocated from heap memory.

(cherry picked from commit 0f1f826)
lhotari added a commit to lhotari/kop that referenced this pull request Feb 11, 2022
- streamnative#1049 changed behavior, therefore this change is needed
BewareMyPower pushed a commit that referenced this pull request Feb 11, 2022
- #1049 changed behavior, therefore this change is needed
BewareMyPower pushed a commit that referenced this pull request Feb 11, 2022
- #1049 changed behavior, therefore this change is needed

(cherry picked from commit bf2331a)
BewareMyPower pushed a commit that referenced this pull request Feb 11, 2022
- #1049 changed behavior, therefore this change is needed

(cherry picked from commit bf2331a)
BewareMyPower pushed a commit that referenced this pull request Feb 11, 2022
- #1049 changed behavior, therefore this change is needed

(cherry picked from commit bf2331a)
eolivelli pushed a commit to eolivelli/kop that referenced this pull request Feb 24, 2022
### Motivation

There is a thread safety issue for `MessageFetchContext`. The instance of that this class could be accessed by different threads. For example, I added some logs to each method and saw the following output:

| Thread name                                 | Method name             |
| ------------------------------------------- | ----------------------- |
| pulsar-io-18-12                             | `MessageFetchContext`   |
| pulsar-io-18-12                             | `handleFetch`           |
| pulsar-io-18-12                             | `handlePartitionData`   |
| pulsar-io-18-12                             | `checkOffsetOutOfRange` |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `readEntries`           |
| BookKeeperClientWorker-OrderedExecutor-10-0 | `handleEntries`         |
| metadata-store-19-1                         | `tryComplete`           |
| metadata-store-19-1                         | `complete`              |
| metadata-store-19-1                         | `recycle`               |

Though all fields are never modified before `recycle()` is called, the visibility of these fields cannot be guaranteed without `volatile`.

### Modifications
- Add `volatile` keyword to fields of `MessageFetchContext` except the atomic variables and thread safe containers.
- For atomic variables and thread safe containers, make them `final` and initialize them in the constructor. In `recycle()` method, instead of resetting them with `null` values, just reset them to the default state.

This PR can also improve the performance. Because even if `MessageFetchContext` is managed by the Netty object pool, each time it's allocated from `MessageFetchContext#get`, the atomic variables and thread safe containers are still allocated from heap memory.

(cherry picked from commit 0f1f826)
eolivelli pushed a commit to eolivelli/kop that referenced this pull request Feb 24, 2022
- streamnative#1049 changed behavior, therefore this change is needed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants