Skip to content
This repository has been archived by the owner on Dec 7, 2018. It is now read-only.

Using Celluloid::IO with existing Ruby libraries

tarcieri edited this page Mar 19, 2013 · 3 revisions

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.

Clone this wiki locally