-
Notifications
You must be signed in to change notification settings - Fork 93
Using Celluloid::IO with existing Ruby libraries
Unlike other non-blocking I/O systems for Ruby like EventMachine and em-synchrony, existing Ruby libraries can be easily modified to work with Celluloid::IO. To do this, the libraries need a dependency injection API which allows a user to specify a different TCPSocket (or UDPSocket, etc) class to use when making network connections. In fact, many Ruby libraries already have APIs like this which let you switch between TCPSocket, OpenSSL::SSL::SSLSocket, and even a TCPSocket duck type that's connected through a proxy server.
Let's imagine we have a Ruby library that doesn't have Celluloid::IO support, and we want to add it. How does that work? Let's imagine the following library:
require 'tcpsocket'
class FoobarConnection
def initialize(host, port)
@socket = TCPSocket.new(host, port)
...
end
end
The problem with this API is that it doesn't allow us to specify what type of socket we with to open. What we need is a dependency injection API which allows us to override TCPSocket and specify a different type of socket connection to open, in this case, a Celluloid::IO::TCPSocket
. Here's one possible API:
require 'tcpsocket'
class FoobarConnection
def initialize(host, port, options = {})
socket_class = options[:socket_class] || TCPSocket
@socket = socket_class.new(host, port)
...
end
end
Easy peasy! Notice we don't need to add any Celluloid::IO-specific code to make this work, since it's implemented entirely with duck types. Instead, existing libraries can easily be modified to use this API. When it comes time to use it, here's all we have to do:
conn = FoobarConnection.new(host, port, :socket_class => Celluloid::IO::TCPSocket)
That's it! You now have a non-blocking Celluloid::IO connection which will seamlessly multiplex with the Celluloid actor protocol.