Skip to content

Conversation

@BewareMyPower
Copy link
Contributor

@BewareMyPower BewareMyPower commented Jul 5, 2022

Motivation

ManagedCursorImpl maintains a field waitingReadOp as the cache of
the OpReadEntry created in asyncReadEntriesOrWait when there are no
more entries to read. However, there are two cases that the created
OpReadEntry are not recycled:

  1. asyncReadEntriesOrWait is called repeatedly when waitingReadOp is
    not null and there are no more entries. The new created OpReadEntry
    cannot pass the CAS check but it's not recycled.
  2. cancelPendingReadRequest is called. The waitingReadOp is just set
    with null and the previous reference is not recycled.

Modifications

For the two cases described above, recycle the OpReadEntry objects.

Verifying this change

Add testOpReadEntryRecycle to reproduce the corner cases and verify the
count of recycle() calls.

Documentation

Check the box below or label this PR directly.

Need to update docs?

  • doc-required
    (Your PR needs to update docs and you will update later)

  • doc-not-needed
    (Please explain why)

  • doc
    (Your PR contains doc changes)

  • doc-complete
    (Docs have been already added)

@github-actions
Copy link

github-actions bot commented Jul 5, 2022

@BewareMyPower Please provide a correct documentation label for your PR.
Instructions see Pulsar Documentation Label Guide.

@github-actions github-actions bot added doc-label-missing doc-not-needed Your PR changes do not impact docs and removed doc-label-missing labels Jul 5, 2022
Copy link
Contributor

@merlimat merlimat left a comment

Choose a reason for hiding this comment

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

👍 I wouldn't mark it as a bug though. It's ok to skip recycling for error condition. It wil just cause the object to be GCed instead of going back to the pool.

@BewareMyPower BewareMyPower changed the title [fix][broker] OpReadEntry is not recycled in some corner cases [improve][broker] OpReadEntry is not recycled in some corner cases Jul 6, 2022
@BewareMyPower BewareMyPower added type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages and removed type/bug The PR fixed a bug or issue reported a bug labels Jul 6, 2022
@BewareMyPower BewareMyPower changed the title [improve][broker] OpReadEntry is not recycled in some corner cases [improve][broker] Recycle OpReadEntry in some corner cases Jul 6, 2022
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.

LGTM

### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

To verify all `OpReadEntry` are recycled correctly, this PRs adds two
static atomic integers to record the create count and the recycle count.
Then add `testOpReadEntryRecycle` to reproduce the corner cases and
verify these counts.
@BewareMyPower BewareMyPower force-pushed the bewaremypower/op-read-entry-recycle branch from b8d77c8 to 7232f22 Compare July 7, 2022 07:03
@BewareMyPower BewareMyPower merged commit 6cec62e into apache:master Jul 7, 2022
@BewareMyPower BewareMyPower deleted the bewaremypower/op-read-entry-recycle branch July 7, 2022 13:27
codelipenghui pushed a commit that referenced this pull request Jul 10, 2022
### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

Add `testOpReadEntryRecycle` to reproduce the corner cases and verify the
count of `recycle()` calls.

(cherry picked from commit 6cec62e)
zymap pushed a commit to zymap/pulsar that referenced this pull request Jul 11, 2022
)

### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

Add `testOpReadEntryRecycle` to reproduce the corner cases and verify the
count of `recycle()` calls.
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Jul 11, 2022
)

### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

Add `testOpReadEntryRecycle` to reproduce the corner cases and verify the
count of `recycle()` calls.

(cherry picked from commit 6cec62e)
(cherry picked from commit 7c37e56)
wuxuanqicn pushed a commit to wuxuanqicn/pulsar that referenced this pull request Jul 14, 2022
)

### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

Add `testOpReadEntryRecycle` to reproduce the corner cases and verify the
count of `recycle()` calls.
mattisonchao pushed a commit that referenced this pull request Jul 15, 2022
### Motivation

`ManagedCursorImpl` maintains a field `waitingReadOp` as the cache of
the `OpReadEntry` created in `asyncReadEntriesOrWait` when there are no
more entries to read. However, there are two cases that the created
`OpReadEntry` are not recycled:
1. `asyncReadEntriesOrWait` is called repeatedly when `waitingReadOp` is
   not null and there are no more entries. The new created `OpReadEntry`
  cannot pass the CAS check but it's not recycled.
2. `cancelPendingReadRequest` is called. The `waitingReadOp` is just set
   with null and the previous reference is not recycled.

### Modifications

For the two cases described above, recycle the `OpReadEntry` objects.

### Verifying this change

Add `testOpReadEntryRecycle` to reproduce the corner cases and verify the
count of `recycle()` calls.

(cherry picked from commit 6cec62e)
@mattisonchao mattisonchao added the cherry-picked/branch-2.9 Archived: 2.9 is end of life label Jul 15, 2022
BewareMyPower added a commit that referenced this pull request Jul 29, 2022
(cherry picked from commit 6cec62e)

In addition to #16399, this PR imports the `mockito-inline` dependency
to fix the test failure.
@BewareMyPower
Copy link
Contributor Author

Move the release/2.8.4 label to #16869

BewareMyPower added a commit that referenced this pull request Aug 1, 2022
(cherry picked from commit 6cec62e)

In addition to #16399, this PR imports the `mockito-inline` dependency
to fix the test failure.
BewareMyPower added a commit that referenced this pull request Aug 2, 2022
#16399) (#16869)

* [improve][broker] Recycle OpReadEntry in some corner cases (#16399)

(cherry picked from commit 6cec62e)

In addition to #16399, this PR imports the `mockito-inline` dependency
to fix the test failure.

* Use PowerMock instead of mockito-inline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/broker cherry-picked/branch-2.9 Archived: 2.9 is end of life cherry-picked/branch-2.10 doc-not-needed Your PR changes do not impact docs release/2.9.4 release/2.10.2 type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants