Skip to content

Async executor tests assert idle right after wait_completion(); engine 7399c0d73 returns a moment earlier #210

Closed

Description

@tae898

What fails

tests/test_async_executor.py fails on the JVM build since the nightly image arcadedata/arcadedb:latest moved to engine commit 7399c0d73 (26.11.1-SNAPSHOT, built 2026-11-03 08:07 UTC). Each failure is an assertion that the executor is idle right after wait_completion() returns:

  • test_async_executor_pending_and_processing_flags (line 201, assert not async_exec.is_pending())
  • test_wait_completion_commits_everything_queued_including_the_tail (line 539)
  • test_async_executor_is_pending_true_while_queued (line 269)

Seen on run 41634526979 (PR #209, attempts 1 and 2) and on the dispatch run 41637991608 (windows, Python 3.11). The push run 41571864536 (commit e1f5499, 03:22 UTC) passed on engine dc99d16b7.

Cause

The two arcadedb-jars artifacts differ only by upstream commits dc99d16b7...7399c0d73. One of them, ArcadeData/arcadedb#11191 (issue #11155), changes DatabaseAsyncExecutorImpl.waitCompletion() from do { onePass } while (isProcessing()) to a loop that goes around again only when a worker scheduled a cascade, and its javadoc now promises only the tasks submitted before the call and what they schedule. The old loop ended with a poll that proved the executor idle at that moment. The new one returns as soon as the last marker has counted down its latch, and the worker clears its executingTask flag a few instructions later (message.completed() runs before executingTask.set(nested) in executeTask). A isProcessing() call from the waiting thread can land in that gap, so it answers true for an instant with nothing left to run.

A Java program that submits 50 records, calls waitCompletion() and asks isProcessing() straight away, 1000 rounds on JDK 25, 2 cores:

engine parallel level isProcessing() true right after waitCompletion() true 1 ms later
dc99d16b7 1 0 of 1000 0 of 1000
dc99d16b7 3 0 of 1000 0 of 1000
7399c0d73 1 48 of 1000 0 of 1000
7399c0d73 3 343 of 1000 0 of 1000

So the engine behaves as its new javadoc says (isProcessing() is a point-in-time answer, and waitCompletion() no longer promises a quiet executor), and these tests asserted a stronger post-condition that the old loop gave by accident. It is a test problem here, not an engine bug that needs a fix to land first.

Fix

Add a helper to the test that waits, with a deadline, for the documented condition (is_processing() false) after wait_completion(), and use it before every "idle now" assertion. Say in the wait_completion() docstring that its return does not make is_pending() false at once. wait_completion(0) on an idle executor has the same exposure (test_async_executor_wait_completion_zero_returns_when_idle), so that test gets the helper too.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions