Skip to content

fix(gateway): track background watcher tasks in _background_tasks - #14748

Closed
sprmn24 wants to merge 1 commit into
NousResearch:mainfrom
sprmn24:feat/whatsapp-send-voice
Closed

fix(gateway): track background watcher tasks in _background_tasks#14748
sprmn24 wants to merge 1 commit into
NousResearch:mainfrom
sprmn24:feat/whatsapp-send-voice

Conversation

@sprmn24

@sprmn24 sprmn24 commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Four asyncio.create_task() calls in gateway/run.py were launched fire-and-forget — the task handles were discarded immediately, so _background_tasks never tracked them. On shutdown, these tasks could not be cancelled or joined, causing orphaned tasks and silently dropped exceptions.

Type of Change

  • Bug fix

Root Cause

The existing pattern used throughout the file is:

task = asyncio.create_task(...)
self._background_tasks.add(task)
task.add_done_callback(self._background_tasks.discard)

Three watcher tasks and the signal handler's runner.stop() call skipped this registration entirely.

Changes Made

  • _run_process_watcher (recovered watchers loop) — each task now stored and registered with discard callback
  • _session_expiry_watcher — task handle stored and registered in _background_tasks
  • _platform_reconnect_watcher — task handle stored and registered in _background_tasks
  • signal handler runner.stop() — stored in _stop_task with exception-logging done callback (_background_tasks not accessible in signal handler scope)

How to Test

  1. Start gateway with a platform that fails at startup (triggers reconnect watcher)
  2. Send Ctrl+C during active processing
  3. Observe clean shutdown with no Task was destroyed but it is pending warnings in logs

Checklist

  • Follows existing _background_tasks pattern used throughout the file
  • No new dependencies
  • Only touches the affected task creation sites

Recovered process watchers, session expiry watcher, and platform
reconnect watcher were launched with asyncio.create_task() but never
registered in _background_tasks. This meant shutdown could not cancel
or join them, leading to orphaned tasks and silent exception drops.

Also guard the signal-handler runner.stop() task with a done callback
that logs any exception instead of silently discarding it.

Fixes:
- _run_process_watcher (recovered watchers loop) — register each task
- _session_expiry_watcher — store handle and register
- _platform_reconnect_watcher — store handle and register
- signal handler runner.stop() — add exception-logging done callback
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery labels Apr 23, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #6790 — same fix: register fire-and-forget watcher tasks in _background_tasks set in GatewayRunner.

1 similar comment
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #6790 — same fix: register fire-and-forget watcher tasks in _background_tasks set in GatewayRunner.

@sprmn24

sprmn24 commented Apr 23, 2026

Copy link
Copy Markdown
Contributor Author

Likely duplicate of #6790 — same fix: register fire-and-forget watcher tasks in _background_tasks set in GatewayRunner.

Thanks for the heads up. Closing - #6790 covers the same fix and goes further with a dedicated helper and regression test.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants