Skip to content

Python dispose() is sync while Node dispose() is async — parity gap #21

Description

@AndresL230

Python dispose() is sync; Node dispose() is async — shutdown semantics differ

Severity: Medium
Affected repos: middleware-python, middleware-node
Component boundary: middleware lifecycle parity

Symptom

  • Node: await handle.dispose() waits for the final flush to complete (bounded by shutdownFlushTimeoutMs).
  • Python: handle.dispose() returns synchronously after spawning a background flush thread, joining it with a 2-second timeout. The final flush may or may not complete.

A user porting a shutdown path from one SDK to the other will get inconsistent behavior. In Python, fast process exit (os._exit() or short-lived scripts) may drop the last window of data.

Evidence

  • middleware-node/src/init.tsdispose() is async, awaits flush.
  • middleware-python/recost/_init.pydispose() is sync, spawns a thread with a short join timeout.

Impact

  • Cross-language users see surprising differences.
  • Pythonists doing graceful shutdown via atexit or signal handler may lose the trailing telemetry window if the runtime tears down before the thread joins.

Fix recommendation

Two options:

  1. Document the difference clearly in both READMEs and CLAUDE.md. Python users should call dispose() and then time.sleep(3) before os._exit() if they want flush guarantees. Cheap.

  2. Add a sync flush call that blocks the calling thread: handle.flush_blocking(timeout_s=3). Then dispose() continues to be best-effort but a deliberate user has an explicit handle.

Recommended: do both. Option 2 is the practical fix; option 1 is the rest of the safety net.

Verification

  • Python test: run a script that emits an event, calls dispose(), exits. Assert (via a mock cloud server) that the event arrived.

Related

Activity

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