Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spawn vs Select for socket handling in Crystal

Which would preform better for handling many socket connections in Crystal?

  1. Spawning a new fiber for each connection passing it the accepted socket object. This would allow the built in async IO handler to switch context between sockets when new data is available to be read.

  2. Implementing a standard select() loop which uses select() to poll sockets for data to be read so that data can be handled.

An example of option 1 could be:

loop do
  accepted_socket = socket.accept
  spawn receive_data(accepted_socket)
end

def receive_data(socket)
  loop do
    #do something useful when data arrives on any socket
    puts socket.gets
  end
end

I am not sure which design would preform better, but I think option 1) would be easier to implement and be more idiomatic to the language. As such you can have many fibers receiving messages from sockets and sending them to a channel, and have another fiber actively receiving messages from the channel for parsing.

Would there be a simple way to attempt to benchmark this?

like image 825
randy newfield Avatar asked Feb 11 '26 22:02

randy newfield


1 Answers

Use a Fiber for each new connection, this will leverage the best poll for your OS, be it epoll, kpoll or another one that we use internally, and are better solutions than the aging select.

Bonus: it just works, you have nothing to do, and we make sure to have the best performance!

like image 194
Julien Portalier Avatar answered Feb 15 '26 11:02

Julien Portalier