Distinction between channels and fibers

I’ve been reading https://crystal-lang.org/reference/guides/concurrency.html and everything makes sense and it’s well-written. Unfortunately, when I got to the Channels section, my mind has exploded.

For example, this TCP Server handles multiple connections easily:

require "socket"

def handle_client(client)
  message = client.gets
  client.puts message
end

server = TCPServer.new("localhost", 1234)
while client = server.accept?
  spawn handle_client(client)
end

Compare that to:

require "socket"

channel = Channel(String).new

spawn do
  server = TCPServer.new("0.0.0.0", 8080)
  socket = server.accept
  while line = socket.gets
    channel.send(line)
  end
end

spawn do
  while line = gets
    channel.send(line)
  end
end

3.times do
  puts channel.receive
end

What exactly is happening when something is “sent through a channel” as compared to “spawned in a fiber”?

The reason I started to look into channels is because I stumbled upon this issue:

I’m trying to understand how/why channels are implemented in their use case example

I would advise you to dive into the source and see for yourself. Start from Fiber.swapcontext and Crystal::Scheduler.resume and see where it takes you.

1 Like

Thanks! I’ll look into those. I’ll refer back to this post if I run into more questions