Skip to content

[ISSUE #10860] Make DefaultPromise.get wait for completion - #11188

Open
beautyarbutin wants to merge 1 commit into
apache:developfrom
beautyarbutin:fix/openmessaging-promise-get
Open

beautyarbutin wants to merge 1 commit into
apache:developfrom
beautyarbutin:fix/openmessaging-promise-get

Conversation

@beautyarbutin

Copy link
Copy Markdown

Which Issue(s) This PR Fixes

Brief Description

The no-argument OpenMessaging DefaultPromise.get() returned the current result immediately, so a pending promise could return null instead of waiting for completion as required by the OpenMessaging API contract.

This change makes get() delegate to the indefinite-wait path, uses a state loop to handle spurious wakeups, and restores the thread interrupt flag when an interrupted wait is cancelled. It also removes listener notification from the read path so listeners remain notified exactly once by promise completion or cancellation.

Tests cover waiting for completion, failure propagation, interrupted waits, and exactly-once listener notification.

How Did You Test This Change?

Before the implementation change, the new blocking test failed because the getter thread terminated instead of entering the waiting state.

mvn -pl openmessaging -am -DskipITs -Dtest=DefaultPromiseTest -Dsurefire.failIfNoSpecifiedTests=false test

Result: 13 tests passed, Checkstyle reported 0 violations, and SpotBugs reported no errors or warnings.

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary

Fixes DefaultPromise.get() to properly block until the promise completes, instead of returning null immediately. Also fixes spurious wakeup handling, narrows exception catch to InterruptedException, restores the thread interrupt flag, and removes a redundant notifyListeners() call in getValueOrThrowable().

Findings

  • [Critical] The original get() returning result immediately violated the OpenMessaging Promise contract. Callers expecting blocking behavior would silently get null. Good fix.
  • [Warning] Removing notifyListeners() from getValueOrThrowable() changes behavior — listeners are now only notified via the completion path (set/setFailure). The test testGetDoesNotNotifyListenerAgain confirms this is intentional (avoids double notification), but worth verifying that no caller depends on getValueOrThrowable() triggering listener notification.
  • [Info] The while (isDoing()) loop correctly handles spurious wakeups. The interrupt handling restores the thread interrupt flag via Thread.currentThread().interrupt(), which is the correct Java idiom.

Overall

Well-implemented fix with comprehensive test coverage (waiting, failure propagation, interrupt handling, listener deduplication). LGTM.


Automated review by RockteMQ-AI

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OpenMessaging DefaultPromise.get returns before completion

2 participants