Skip to content

[#2398] FutureBrokerInfoTimeout is missed due to logic operator error - #2399

Open
mattrpav wants to merge 2 commits into
apache:mainfrom
mattrpav:amq-gh-2398-futurebrokerinfotimeout
Open

[#2398] FutureBrokerInfoTimeout is missed due to logic operator error#2399
mattrpav wants to merge 2 commits into
apache:mainfrom
mattrpav:amq-gh-2398-futurebrokerinfotimeout

Conversation

@mattrpav

@mattrpav mattrpav commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

No description provided.

The timed get loop's condition uses || between the not-disposed check and
the deadline check, so the loop runs until disposal regardless of the
caller's timeout. Widens FutureBrokerInfo to package-private so the test
drives the real class. Two of four scenarios fail until the condition is
corrected.
Correct the loop condition from || to && so the timed get exits when
EITHER the bridge is disposed OR the deadline expires. Previously a peer
that never delivered its BrokerInfo parked the bridge start thread until
disposal, ignoring the caller's timeout.
AtomicBoolean timedOut = new AtomicBoolean(false);
AtomicLong elapsed = new AtomicLong(-1);

Thread t = new Thread(() -> {

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.

I would re-write these tests and use an executor, it's simpler/cleaner. Here's an example for this test but it applies to all the tests.

@Test(timeout = 10000)
public void testGetTimedThrowsTimeoutExceptionWithinTimeout() throws Exception {
    AtomicBoolean disposed = new AtomicBoolean(false);
    FutureBrokerInfo future = new FutureBrokerInfo(null, disposed);

    AtomicBoolean timedOut = new AtomicBoolean(false);
    AtomicLong elapsed = new AtomicLong(-1);

    ExecutorService executor = Executors.newSingleThreadExecutor();

    executor.submit(() -> {
        long start = System.currentTimeMillis();
        try {
            future.get(200, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            timedOut.set(true);
        } catch (Exception ignored) {
        } finally {
            elapsed.set(System.currentTimeMillis() - start);
        }
    });
    executor.shutdown();
    assertTrue("get(200ms) should have returned within 3s but is still blocked "
            + "- the timeout is being ignored",
            executor.awaitTermination(3, TimeUnit.SECONDS));
    
    assertTrue("Expected TimeoutException from get(200ms)", timedOut.get());
    assertTrue("Timed out too early: " + elapsed.get() + "ms", elapsed.get() >= 180);
}

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.

also it might be worth wrapping the assertion in a try/finally just in case it get stuck:

        try {
            assertTrue("get(200ms) should have returned within 3s but is still blocked "
                            + "- the timeout is being ignored",
                    executor.awaitTermination(3, TimeUnit.SECONDS));
        } finally {
            executor.shutdownNow();
        }

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

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants