62 lines
1.7 KiB
Ruby
62 lines
1.7 KiB
Ruby
require 'hydra/messaging_io'
|
|
module Hydra #:nodoc:
|
|
# Read and write between two processes via pipes. For example:
|
|
# @pipe = Hydra::Pipe.new
|
|
# @child = Process.fork do
|
|
# @pipe.identify_as_child
|
|
# puts "A message from my parent:\n#{@pipe.gets.text}"
|
|
# @pipe.close
|
|
# end
|
|
# @pipe.identify_as_parent
|
|
# @pipe.write Hydra::Messages::TestMessage.new(:text => "Hello!")
|
|
# @pipe.close
|
|
#
|
|
# Note that the TestMessage class is only available in tests, and
|
|
# not in Hydra by default.
|
|
#
|
|
#
|
|
# When the process forks, the pipe is copied. When a pipe is
|
|
# identified as a parent or child, it is choosing which ends
|
|
# of the pipe to use.
|
|
#
|
|
# A pipe is actually two pipes:
|
|
#
|
|
# Parent == Pipe 1 ==> Child
|
|
# Parent <== Pipe 2 == Child
|
|
#
|
|
# It's like if you had two cardboard tubes and you were using
|
|
# them to drop balls with messages in them between processes.
|
|
# One tube is for sending from parent to child, and the other
|
|
# tube is for sending from child to parent.
|
|
class Pipe
|
|
include Hydra::MessagingIO
|
|
# Creates a new uninitialized pipe pair.
|
|
def initialize
|
|
@child_read, @parent_write = IO.pipe
|
|
@parent_read, @child_write = IO.pipe
|
|
end
|
|
|
|
# Identify this side of the pipe as the child.
|
|
def identify_as_child
|
|
@parent_write.close
|
|
@parent_read.close
|
|
@reader = @child_read
|
|
@writer = @child_write
|
|
end
|
|
|
|
# Identify this side of the pipe as the parent
|
|
def identify_as_parent
|
|
@child_write.close
|
|
@child_read.close
|
|
@reader = @parent_read
|
|
@writer = @parent_write
|
|
end
|
|
|
|
# Output pipe nicely
|
|
def inspect
|
|
"#<#{self.class} @reader=#{@reader.to_s}, @writer=#{@writer.to_s}>"
|
|
end
|
|
|
|
end
|
|
end
|