Skip to content

fix(clob): keep heartbeats alive across client clones - #92

Open
mattfaltyn wants to merge 1 commit into
Polymarket:mainfrom
mattfaltyn:agent/fix-heartbeat-clone-drop
Open

fix(clob): keep heartbeats alive across client clones#92
mattfaltyn wants to merge 1 commit into
Polymarket:mainfrom
mattfaltyn:agent/fix-heartbeat-clone-drop

Conversation

@mattfaltyn

@mattfaltyn mattfaltyn commented Jul 19, 2026

Copy link
Copy Markdown

Summary

  • cancel the automatic heartbeat task only when the final DroppingCancellationToken owner is dropped
  • keep heartbeats running when temporary Client clones, including order-builder clones, are consumed or dropped
  • add a bounded-polling integration regression that verifies heartbeats continue after dropping a limit-order builder and can still be stopped explicitly

Root cause

Client and DroppingCancellationToken both derive Clone, but every cloned wrapper previously called CancellationToken::cancel() from Drop. OrderBuilder embeds a cloned client, so completing or dropping a normal order builder silently terminated the shared heartbeat task while the original client continued reporting heartbeats_active() == true.

The fix uses Arc::into_inner to atomically identify the final receiver owner. This preserves existing explicit-stop and multiple-owner synchronization behavior while ensuring exactly one final drop performs cancellation, including under concurrent drops.

Impact

Heartbeat-enabled clients can build orders without silently stopping the dead-man heartbeat mechanism and risking order-priority loss or cancellation of open orders.

Validation

  • cargo build --all-targets --all-features
  • cargo test — 15 unit tests and 4 doctests passed; feature-gated integrations correctly skipped
  • cargo +nightly-2025-11-24 fmt --all -- --check
  • cargo +1.88 clippy --all-targets --all-features -- -D warnings
  • cargo +1.88 clippy --all-targets -- -D warnings
  • cargo sort --check with cargo-sort 2.0.2
  • cargo +1.88 llvm-cov --all-features --workspace --lcov --output-path lcov.info — 559 all-feature tests passed
  • PRE_COMMIT_HOME=/tmp/pre-commit pre-commit run --files src/clob/client.rs tests/clob.rs
  • focused heartbeat regression passed 20 consecutive runs

Fixes #91


Note

Medium Risk
Touches shared heartbeat teardown for all authenticated client clones; wrong refcount logic could leave heartbeats running or stop them too early, but scope is narrow and covered by a new regression test.

Overview
Fixes a bug where dropping any cloned Client (including a temporary limit-order builder) cancelled the shared heartbeat task while the main client still reported heartbeats as active.

DroppingCancellationToken’s Drop now calls CancellationToken::cancel() only when the dropped instance holds the last Arc to the cleanup receiver (Arc::into_inner), so intermediate clones from limit_order() / market_order() no longer stop the background heartbeat loop. Explicit stop_heartbeats / cancel_and_wait behavior is unchanged.

Adds a heartbeats integration test that drops a limit-order builder, asserts heartbeats keep posting, then verifies stop_heartbeats still shuts them down.

Reviewed by Cursor Bugbot for commit 03fa66a. Bugbot is set up for automated code reviews on this repo. Configure here.

@mattfaltyn
mattfaltyn marked this pull request as ready for review July 19, 2026 19:16
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.

Heartbeats stop when an order builder is dropped

1 participant