Skip to content

Close fiber_channel on Server#shutdown to avoid fiber leak. Fixes #110#111

Open
russ wants to merge 1 commit into
cable-cr:masterfrom
russ:fix/close-fiber-channel-on-shutdown
Open

Close fiber_channel on Server#shutdown to avoid fiber leak. Fixes #110#111
russ wants to merge 1 commit into
cable-cr:masterfrom
russ:fix/close-fiber-channel-on-shutdown

Conversation

@russ

@russ russ commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

During Server#shutdown the fiber_channel (::Channel({String, String})) was never closed. The process_subscribed_messages fiber reads from it in a forever-loop (while received = fiber_channel.receive), and the producer side lives in the external cable-redis shard (Cable.server.fiber_channel.send(...)).

Because Cable.restart builds a brand-new Server — with a brand-new fiber_channel — on every restart, each shutdown left the old fiber blocked on receive against an orphaned channel. That's a fiber + channel leak that accumulates across restarts.

Fixes #110.

Changes

  • Server#shutdown now calls fiber_channel.close after closing connections (where the issue author suggested).
  • The receive loop switches from receive to receive?. This is necessary because calling receive on a closed channel raises Channel::ClosedError, which would crash the spawned fiber with an unhandled exception. receive? returns nil on close, so the loop exits cleanly.

Tests

  • Added a regression spec in spec/cable/server_spec.cr asserting that after shutdown the fiber_channel is closed and a subsequent send raises.
  • Full suite passes: 52 examples, 0 failures, 0 errors, 0 pending.

🤖 Generated with Claude Code

…le-cr#110

During Server#shutdown the fiber_channel was never closed, so the
process_subscribed_messages fiber was left blocked on receive against an
orphaned channel. Since Cable.restart builds a fresh Server (with a fresh
channel) on every restart, each restart leaked a fiber and channel.

Close the channel at the end of shutdown, and switch the receive loop to
receive? so the fiber exits cleanly instead of raising Channel::ClosedError
on a closed channel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMW1EsdCMExBhm3tg7TQhs
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.

When a server shuts down, the fiber channel is never closed

1 participant