没有外部程序比没有更好的方法来进行跨进程队列吗?

时间:2009-07-13 22:08:30

标签: ruby

我在函数中有以下代码:

num_procs.times do

  pid = fork
  unless pid
    DRb.start_service
    ts = Rinda::TupleSpaceProxy.new(DRbObject.new_with_uri('druby://localhost:53421'))

    loop do
      item = ts.take([:enum, nil, nil])

      # our termination tuple
      break if item == [:enum, -1, nil]
      result =
        begin
          block.call(item[2])
        rescue Object => e
          e
        end

      # return result
      ts.write([:result, item[1], result])

    end
    DRb.stop_service
    exit!
  end

  pids << pid
end

pts = Rinda::TupleSpace.new
# write termination tuples
items.size.times do
  pts.write([:enum, -1, nil])
end

items.each_with_index { |item, index|
  pts.write([:enum, index, item])
}

DRb.start_service('druby://localhost:53421', pts)

# Grab results
items.size.times do
  result_tuples << pts.take([:result, nil, nil])
end

pp "Waiting for pids: #{pids.inspect}" if FORKIFY_DEBUG
pids.each { |p| Process.waitpid(p)  }

DRb.stop_service

# gather results and sort them
result_tuples.map { |t|
  results[t[1]] = t[2]
}

return results

这段代码分叉了很多次,然后孩子们尝试使用Rinda :: TupleSpaceProxy而不是DRb从父级获取元组。父项为每个进程推送项目以调用块。然后,孩子们将不同元组的结果返回给父级,父级将它们聚合在一起。

此代码位于库中,因此我不希望用户必须启动类似beanstalkd或类似的东西才能为进程池排队作业。我的问题是:

我是否有更好的方法可以进行跨进程队列通信?

1 个答案:

答案 0 :(得分:0)

(我尝试运行上面的代码,但即使经过一些调整和要求,我也无法实现它,所以请不要赘述这个建议。)

而不是DRb,最好选择beanstalk / delayed_job / [other queue]依赖关系。如果这只是一个后台工作,我建议dj,因为它是众所周知的并且易于入手(参见this example快速入门)。如果您可以发布更多代码,那么它会更容易帮助。