Repository navigation
fix: prevent sender control future race - #357
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a control-message future race in the computer-core message-sending pipeline (specifically QueuedMessageSender) that could surface as The origin future must be null, and also tightens computer-test integration behavior to fail faster instead of stalling for long BSP timeouts.
Changes:
- Refactors control-message handling in
QueuedMessageSenderso each START/FINISH message carries its ownCompletableFuture, and the in-flight control future is cleared before completion. - Adds unit regressions for consecutive control messages and for transport failures completing the control future exceptionally.
- Updates sender integration tests to apply shorter BSP wait timeouts and to use a bounded
waitForServices()helper.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/integrate/SenderIntegrateTest.java | Adds CI-oriented BSP/service timeouts and a fail-fast wait helper for master/worker futures |
| computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/sender/QueuedMessageSenderTest.java | Adds regressions for control-future sequencing and transport exception completion |
| computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/sender/QueuedMessageSender.java | Refactors control-message future lifecycle and transport-exception handling |
| computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/sender/QueuedMessage.java | Extends queued message model to optionally carry a control future |
Comments suppressed due to low confidence (2)
computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/sender/QueuedMessageSender.java:273
- Same issue as
sendStartMessage(): ifsetControlFuture()throwsComputerException, it will currently bubble out ofsendFinishMessage()and can terminate the send-executor thread. Since the future is already completed exceptionally insetControlFuture(), catchComputerExceptionhere and return to avoid killing the sender thread.
public void sendFinishMessage(CompletableFuture<Void> future)
throws TransportException {
this.setControlFuture(future);
try {
this.client.finishSessionAsync().whenComplete((r, e) -> {
computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/integrate/SenderIntegrateTest.java:122
- The master options set
withRpcServerPort()twice (8611then0). The first value is immediately overridden and can be misleading when debugging port binding issues; it’s clearer to keep only the effective port setting.
.withRpcServerHost("127.0.0.1")
.withRpcServerPort(8611)
.withRpcServerPort(0)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: An existing review thread covers the sender-executor termination risk, and the new fail-fast service wait can race past lifecycle cleanup. Evidence: exact-head static inspection by six independent lanes; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Synchronous runtime failures can still strand an in-flight control future, and the fail-fast cleanup/tests leave concurrency gaps. Evidence: six independent exact-head review lanes; targeted QueuedMessageSenderTest passed; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Two control-message failure windows can still strand work or hide a connection failure, and initialization failures can bypass the new cleanup path; latest-head Computer CI is also failing. Evidence: exact-head static interleaving analysis; local Maven validation stopped before the target test because the available JDK cannot compile computer-k8s; GitHub Actions run 30206151982 reports three unit-test failures.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Two fail-fast cleanup paths can still extend CI stalls and hide the original service failure. Evidence: six independent exact-head review lanes; QueuedMessageSenderTest passed 7/7 on JDK 11; git diff --check passed; visible exact-head checks were green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: A synchronous data-path failure can still terminate the sole sender and strand queued control futures, while two new cleanup tests can leak non-daemon threads on an early assertion failure. Evidence: six independent exact-head review lanes; QueuedMessageSenderTest passed 7/7 on JDK 11; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: An uncaught master Error can leave the service future pending until the five-minute timeout; two previously reported sender and cleanup risks also remain covered by existing threads. Evidence: six independent exact-head review lanes, static control-flow and interleaving analysis, QueuedMessageSenderTest passed 9/9, and visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: A data-send failure can still be forgotten before FINISH is registered, allowing the step to succeed after silently dropping a message; the new timeout regression also has a minor timing-flake window. Evidence: six independent exact-head review lanes; static MessageSendManager/QueuedMessageSender interleaving analysis; targeted QueuedMessageSenderTest passed 9/9; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: A control-completion race can silently discard transport failures, and service cleanup errors can still be hidden after successful execution. Evidence: six independent exact-head review lanes; targeted QueuedMessageSenderTest passed 12/12 on JDK 11; git diff --check passed; visible exact-head checks are green.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/integrate/SenderIntegrateTest.java:91
- The master options builder sets rpcServerPort twice (8611 and then 0). This is redundant and makes it harder to tell which port is actually used;
convertToMap()will silently let the later value win. Please remove the fixed port and keep only the ephemeral port (0).
.withRpcServerHost("127.0.0.1")
.withRpcServerPort(8611)
.withRpcServerPort(0)
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Partial worker initialization can now omit the BSP close signal, and the integration tests have reverted to unbounded 24-hour BSP waits on failure. Evidence: six independent exact-head review lanes; QueuedMessageSenderTest passed 15/15 on JDK 11; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Two test changes weaken coverage of sender backpressure and executor shutdown behavior. Evidence: six independent exact-head review lanes; targeted QueuedMessageSenderTest passed 15/15 on JDK 11; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: The partial-initialization regression test bypasses the production registration transition, so it cannot catch the lifecycle bug returning. Evidence: five completed independent exact-head review lanes; one additional lane ended without a result; QueuedMessageSenderTest passed 15/15 on JDK 11; git diff --check passed; visible exact-head checks are green.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: no. Summary: The sender control-future and partial worker-initialization paths are consistent at this head, with no actionable findings after independent review. Evidence: six exact-head review lanes; QueuedMessageSenderTest 15/15 and WorkerServiceTest#testInitFailsAfterRegistration 1/1 passed on JDK 11; git diff --check passed; all visible exact-head checks are green. Score: 8.6/10.
bitflicker64
left a comment
There was a problem hiding this comment.
Blocking: no. Summary: The control-future rework is sound and its 15 unit regressions pass locally at this head, but two gaps remain on the failure paths the PR targets: partially initialized worker managers are still only half closed because Managers.closeAll() aborts at the first failing manager, and a fatal send-executor error leaves already-queued control futures unresolved so callers still wait the full 10s/80s transport timeout and get a misleading Timeout(...) instead of the recorded cause. Evidence: mvn install -DskipTests then java -cp <computer-test classpath> org.junit.runner.JUnitCore org.apache.hugegraph.computer.core.sender.QueuedMessageSenderTest -> OK (15 tests); WorkerServiceTest#testInitFailsAfterRegistration -> RESULT run=1 failures=0; two standalone probes compiled against 8492fd4 reproduce the two gaps (outputs quoted inline).
bitflicker64
left a comment
There was a problem hiding this comment.
Blocking: no. Summary: The latest commit closes the queued-control-future and partial-cleanup gaps from the previous round, but two small failure-path gaps remain: an unexpected interrupt on an idle send-executor still exits without recording a fatal error, and WorkerInputManager still throws an NPE when closed after a partial init. Evidence: JDK 11 test-compile of computer-test at 5189d79; QueuedMessageSenderTest OK (17 tests); DataServerManagerTest#testCloseManagersAfterPartialInitFailure and WorkerServiceTest#testInitFailsAfterRegistration pass; two standalone probes against this head reproduce both gaps (outputs inline); all checks on this head are green.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #357 +/- ##
============================================
+ Coverage 85.03% 85.32% +0.29%
- Complexity 3296 3401 +105
============================================
Files 349 362 +13
Lines 12485 12839 +354
Branches 1130 1186 +56
============================================
+ Hits 10616 10955 +339
- Misses 1329 1352 +23
+ Partials 540 532 -8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Purpose of the PR
Main Changes
sequenceDiagram autonumber participant Master participant ServiceThread as ServiceThread(init) participant MainThread as MainThread(close) ServiceThread->>Master: workerInitDone() Note over Master: master 把该 worker 计入名单,<br/>开始等待它的 workerCloseDone() ServiceThread->>ServiceThread: registered = true ServiceThread->>ServiceThread: connectToWorkers() 失败! ServiceThread-->>ServiceThread: init() 抛出异常 (inited 仍为 false) MainThread->>MainThread: close() 被调用 MainThread->>MainThread: OLD: if (this.inited) → false → 跳过 workerCloseDone() Master->>Master: 等 workerCloseDone(),最长 24h Note over Master: ⚠️ 死锁 / 超时Tests
QueuedMessageSenderTestandIntegrateTestSuite.Verifying these changes
Does this PR potentially affect the following parts?
Documentation Status
Doc - TODODoc - DoneDoc - No Need