Skip to content

[fix][client] In method LastCumulativeAck#update, bitSetRecyclable does not update when messageId is equal.#18154

Closed
lordcheng10 wants to merge 1 commit intoapache:masterfrom
lordcheng10:fix_LastCumulativeAck_update
Closed

[fix][client] In method LastCumulativeAck#update, bitSetRecyclable does not update when messageId is equal.#18154
lordcheng10 wants to merge 1 commit intoapache:masterfrom
lordcheng10:fix_LastCumulativeAck_update

Conversation

@lordcheng10
Copy link
Contributor

@lordcheng10 lordcheng10 commented Oct 21, 2022

Motivation

In method LastCumulativeAck#update, bitSetRecyclable does not update when messageId is equal:

public synchronized void update(final MessageIdImpl messageId, final BitSetRecyclable bitSetRecyclable) {
if (messageId.compareTo(this.messageId) > 0) {
if (this.bitSetRecyclable != null && this.bitSetRecyclable != bitSetRecyclable) {
this.bitSetRecyclable.recycle();
}
set(messageId, bitSetRecyclable);
flushRequired = true;
}
}

Modifications

When the messageId is equal, but the batch index is larger, the bitSetRecyclable should be updated:

   public synchronized void update(final MessageIdImpl messageId, final BitSetRecyclable bitSetRecyclable) {
        if (messageId.equals(this.messageId)) {
            if (this.bitSetRecyclable != null && bitSetRecyclable != null
                    && bitSetRecyclable.nextSetBit(0) > this.bitSetRecyclable.nextSetBit(0)) {
                this.bitSetRecyclable.recycle();
                set(messageId, bitSetRecyclable);
                flushRequired = true;
            }
            return;
        }

        if (messageId.compareTo(this.messageId) > 0) {
            if (this.bitSetRecyclable != null && this.bitSetRecyclable != bitSetRecyclable) {
                this.bitSetRecyclable.recycle();
            }
            set(messageId, bitSetRecyclable);
            flushRequired = true;
        }
    }

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository: lordcheng10#36

return;
}

if (messageId.compareTo(this.messageId) > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We already have the compare sult, I think we can improve it like

        int compareResult = messageId.compareTo(this.messageId);
        if (messageId.compareTo(this.messageId) > 0) {
            /* ... */
        } else if (compareResult == 0) {
            /* compare bitSetRecyclable... */
        }

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

return;
}

if (messageId.compareTo(this.messageId) > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

seem compareTo has already compare the batchIndex.

return ComparisonChain.start()
.compare(ledgerId1, ledgerId2)
.compare(entryId1, entryId2)
.compare(partitionIndex1, partitionIndex2)
.compare(batchIndex1, batchIndex2)
.result();
so we don't need to do single check, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are right

Copy link
Contributor

@BewareMyPower BewareMyPower left a comment

Choose a reason for hiding this comment

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

Actually I have another question. Could it happen in a real world case?

When the BitSetRecyclable object is not null, the messageId argument must be a BatchMessageIdImpl.

BitSetRecyclable bitSet = BitSetRecyclable.create();
bitSet.set(0, batchMessageId.getBatchSize());
bitSet.clear(0, batchMessageId.getBatchIndex() + 1);
return doCumulativeAck(batchMessageId, null, bitSet);

If messageId.equals(this.messageId), it must means this.messageId has the same batch index with messageId. In this case, could bitSetRecyclable be different with this.bitSetRecyclable?

@lordcheng10
Copy link
Contributor Author

If messageId.equals(this.messageId), it must means this.messageId has the same batch index with messageId.

Yes,you are right!

Can the bitSetRecyclable variable be removed? Because we can know which sub-messages have been acknowledged just by the batch index:@BewareMyPower
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/client doc-not-needed Your PR changes do not impact docs release/2.11.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants