Skip to content

[fix][ml] Propagate cursor ledger deletion failures - #26734

Merged
lhotari merged 1 commit into
apache:masterfrom
zhanghaou:fix-delete-cursor
Sep 28, 2026
Merged

lhotari merged 1 commit into
apache:masterfrom
zhanghaou:fix-delete-cursor

Conversation

@zhanghaou

Copy link
Copy Markdown
Contributor

Motivation

When deleting a managed ledger that is not open in the factory, ManagedLedgerFactoryImpl.deleteCursor() returns a separate future that is completed only by the cursor metadata removal callbacks.

If BookKeeper fails to delete the cursor ledger with an error other than a missing-ledger error, the deletion stage completes exceptionally and the following thenRun() is skipped. The returned future remains incomplete because the failure is not propagated to it.

For example, with a single cursor, a metadata deletion error reported as ZKException prevents asyncDelete() from invoking either callback. The synchronous delete() can consequently remain blocked on its latch.

Modifications

  • Propagate failures from the thenRun() stage to the future returned by deleteCursor().
  • Preserve the existing behavior of continuing metadata cleanup when the cursor ledger no longer exists.
  • Add regression tests for metadata deletion failure, successful deletion, and both supported missing-ledger error codes.

Verifying this change

This change adds tests in ManagedLedgerFactoryTest:

  • Inject a ZKException error code for cursor ledger deletion and verify that the failure reaches the caller while cursor metadata remains intact.
  • Verify successful cleanup after normal deletion and both missing-ledger errors.

The failure regression was run against the unpatched implementation and failed with a timeout while waiting for the deletion callback. With the fix, all 6 test invocations in ManagedLedgerFactoryTest pass.

The failure is injected through Mock BookKeeper; the test does not disconnect a live ZooKeeper service.

Local validation passed:

./gradlew :managed-ledger:test \
  --tests "org.apache.bookkeeper.mledger.impl.ManagedLedgerFactoryTest" \
  -PtestRetryCount=0
./gradlew quickCheck

Does this pull request potentially affect one of the following parts:

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Complete the returned future exceptionally when cursor ledger deletion fails. Add regression coverage for metadata deletion errors, successful deletion, and missing ledgers.

Assisted-by: Codex

@lhotari lhotari left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@lhotari
lhotari merged commit 0e75593 into apache:master Sep 28, 2026
44 checks passed
ascentstream-bot pushed a commit to ascentstream/pulsar that referenced this pull request Oct 1, 2026
ascentstream-bot pushed a commit to ascentstream/pulsar that referenced this pull request Oct 2, 2026
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.

3 participants