我试图在使用多核的仅使用Ruby的解决方案中模拟UNIX命令行管道。最终,从命令到命令管道的记录将是使用msgpack封送的Ruby对象。不幸的是,下面的代码在第一个dump命令后挂起。我怀疑管道死锁,但我无法解决它?
#!/usr/bin/env ruby
require 'parallel'
require 'msgpack'
require 'pp'
class Pipe
def initialize
@commands = []
end
def add(command, options = {})
@commands << Command.new(command, options)
self
end
def run
@commands.each_cons(2) do |c_in, c_out|
reader, writer = IO.pipe
c_out.input = MessagePack::Unpacker.new(reader)
c_in.output = MessagePack::Packer.new(writer)
end
Parallel.each(@commands, in_processes: @commands.size) { |command| command.run }
self
end
class Command
attr_accessor :input, :output
def initialize(command, options)
@command = command
@options = options
@input = nil
@output = nil
end
def run
send @command
end
def cat
@input.each_with_index { |record, i| @output.write(record).flush } if @input
File.open(@options[:input]) do |ios|
ios.each { |record| @output.write(record).flush } if @output
end
end
def dump
@input.each do |record|
puts record
@output.write(record).flush if @output
end
end
end
end
p = Pipe.new
p.add(:cat, input: "foo.tab").add(:dump).add(:cat, input: "table.txt").add(:dump)
p.run