Object Channel
In some testing scenarios (such as signal handling), it is helpful to be able to test from outside a process; common methods for communicating between two ends of a fork include pushing data to an intermediary, such as a database or filesystem, but both have side-effects: additional dependencies (many of which have their own dependencies) and/or the need for post-run cleanup.
To avoid this, I often use IO.pipe:
reader,writer = IO.pipe
child_pid = fork do
reader.close
writer.write( "Hello, I'm #{Process.pid}" )
writer.close
end
writer.close
= reader.read
reader.close
puts Process.pid # => 12338
puts child_pid # => 12345
puts # => "Hello, I'm 12345"
But that has several drawbacks:
read
only works if allwrite
ends of the pipe are closed; keeping track of which is open and which is closed is a pain, especially if you have to fork several layers deep.- only a single message can be passed; multiple messages adds complexity, and complicated test cases aren't a good idea
- only strings can be passed; sure Objects can be serialized, but...
A Simpler Way
Adding this kind of logic directly into your tests is a bad idea; it makes them
unnecessarily complicated, hard to read, and easy to get wrong. ObjectChannel
abstracts all that away so you can just test. Here's the same simple example, but
this time without all the pipe-closing:
require 'object-channel'
p2c = ObjectChannel.fork do |c2p|
c2p.transmit( "Hello, I'm #{Process.pid}" )
end
puts Process.pid # => 12338
puts p2c.pid # => 12345
puts p2c.receive! # => "Hello, I'm 12345"
Features
ObjectChannel
provides the following features:
- Full-fledged objects, not just strings
- Bi-directional channel
- Blocking and non-blocking access
- block-invoke supported and fully optional
- No additional dependencies
- No cleanup necessary
Check out the specs for examples.
License & Contributing
Project is (c) 2012 Simply Measured and released under an MIT-style license
- This project uses Vincent Driessen's Git-Flow branching model.
- Check out the latest develop to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.