Skip to content

fix(swarm): shutdown does not close lifecycle admission #771

Description

@PierrunoYT

Summary

Swarm.Close cancels the base context but does not record a closed state or wait for member lifecycle watchers. Calls made after shutdown begins can still register tasks and launch work with an already-canceled context, while existing watchers may continue retrying or draining queued members.

This tracks AUD-010 from the July 18 codebase audit.

Affected code

  • internal/swarm/team.go:139-152
  • internal/swarm/lifecycle.go:14-27
  • internal/swarm/lifecycle.go:62-167

Current behavior

Shutdown cancellation is not coupled to lifecycle admission or watcher completion:

  • lifecycle operations can still be admitted after Close;
  • new work can launch with a canceled context;
  • existing watchers can retry or drain queued members after shutdown begins; and
  • Close can return without waiting for lifecycle goroutines to finish.

Expected behavior

After shutdown begins, the swarm should reject new lifecycle work and prevent retries or queue draining. Close should not return until owned lifecycle watchers have exited.

Suggested implementation

  • Add an atomic or mutex-protected closed state.
  • Mark the swarm closed before canceling its base context.
  • Reject lifecycle admission after close.
  • Track lifecycle watchers with a sync.WaitGroup or equivalent ownership mechanism.
  • Stop retry and queue-drain paths once cancellation or closed state is observed.
  • Wait for watcher completion before Close returns.

Suggested tests

  • Lifecycle registration and launch attempts after Close are rejected.
  • Shutdown prevents queued members from being started.
  • Retry paths stop once shutdown begins.
  • Close waits for active lifecycle watchers to exit.
  • Concurrent Close and lifecycle admission cannot launch post-close work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions