Which would preform better for handling many socket connections in Crystal?
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.
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?
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With