module
Rubellite::Docs::B_ADVANCED_FEATURES::CHANNEL_CONCURRENCY
Overview
Channel Concurrency & Fiber Interop
Crystal utilizes lightweight Fibers with non-blocking event loops, while CRuby relies on native OS threads constrained by the Global VM Lock (GVL / GIL).
Rubellite builds a thread-safe bridge (Rubellite::ChannelBridge) enabling Crystal fibers
to stream values directly into Ruby scripts and vice versa without deadlocking the host process.
Executive Summary & Key Topics
| Topic | Method / Anchor | Description |
|---|---|---|
| ChannelBridge Architecture & Pipeline Streaming | .topic_01_channel_bridge |
Bidirectional asynchronous communication between Crystal fibers and Ruby with Queue compatibility. |
Related Guides & Source References
- src/rubellite/channel.cr
- src/rubellite/concurrency.cr
- examples/05_channel_and_fiber_concurrency.cr
Defined in:
rubellite/docs/b_advanced_features/channel_concurrency.crClass Method Summary
-
.topic_01_channel_bridge : Nil
ChannelBridge Architecture & Pipeline Streaming: Bidirectional asynchronous communication between Crystal fibers and Ruby with Queue compatibility.
Class Method Detail
ChannelBridge Architecture & Pipeline Streaming: Bidirectional asynchronous communication between Crystal fibers and Ruby with Queue compatibility.
The Rubellite::ChannelBridge exposes send and receive primitives directly to Ruby scripts:
| Action | Crystal API | Ruby Script Equivalent | ||
|---|---|---|---|---|
| **Send** | `channel.send(value)` | `queue.send(val)`, `queue.push(val)`, `queue << val`, `queue.enq(val)` | ||
| **Receive** | `channel.receive` | `queue.receive`, `queue.pop`, `queue.deq`, `queue.shift` | ||
| **Safe Receive** | `channel.receive?` | `queue.receive?` (returns `nil` on close) | ||
| **Iteration** | `while val = chan.receive?` | `queue.each { | item | ... }` (Enumerable streaming) |
| **Close** | `channel.close` | `queue.close`, `queue.closed?` |
Working Examples
require "rubellite"
# Create typed Crystal channel and export to Ruby
in_chan = Channel(String).new(10)
Rubellite.export_channel("work_queue", in_chan)
# Producer fiber
spawn do
["job_alpha", "job_beta", "job_gamma"].each do |task|
in_chan.send(task)
end
in_chan.close
end
# Ruby consumes using idiomatic Enumerable iteration
Ruby.eval(<<-RUBY)
work_queue.each do |task|
puts "Ruby processing \#{task}"
end
RUBY
Common Pitfalls & Safety Caveats
- Warning: Ruby
receivereleases the GVL viarb_thread_call_without_gvl, allowing other Ruby threads and Crystal fibers to progress while waiting. - Warning: Multi-fiber concurrent evaluations are serialized safely with re-entrant synchronization (
Ruby.synchronize). - Warning: Always close channels when producers terminate to avoid leaving Ruby consumer fibers hanging.
Frequently Asked Questions (FAQ)
- Q: Is Channel communication thread-safe? A: Yes, Rubellite synchronizes channel access using Crystal spinlocks and mutexes around Ruby GVL transitions.