我在Celluloid中实现了一个简单的程序,理想情况下会并行运行一些actor,每个actor都会计算一些东西,然后将其结果发送回一个主要角色,其主要工作就是聚合结果
关注this FAQ,我引入了SupervisionGroup
,如下所示:
module Shuffling
class AggregatorActor
include Celluloid
def initialize(shufflers)
@shufflerset = shufflers
@results = {}
end
def add_result(result)
@results.merge! result
@shufflerset = @shufflerset - result.keys
if @shufflerset.empty?
self.output
self.terminate
end
end
def output
puts @results
end
end
class EvalActor
include Celluloid
def initialize(shufflerClass)
@shuffler = shufflerClass.new
self.async.runEvaluation
end
def runEvaluation
# computation here, which yields result
Celluloid::Actor[:aggregator].async.add_result(result)
self.terminate
end
end
class ShufflerSupervisionGroup < Celluloid::SupervisionGroup
shufflers = [RubyShuffler, PileShuffle, VariablePileShuffle, VariablePileShuffleHuman].to_set
supervise AggregatorActor, as: :aggregator, args: [shufflers.map { |sh| sh.new.name }]
shufflers.each do |shuffler|
supervise EvalActor, as: shuffler.name.to_sym, args: [shuffler]
end
end
ShufflerSupervisionGroup.run
end
我完成后终止了EvalActor
,并在完成所有工作后终止AggregatorActor
。
然而,监督线程保持活跃并使主线程保持活动状态。该程序永远不会终止。
如果我向组发送.run!
,那么主线程就会在它之后终止,并且没有任何效果。
在finalize
终止后,我可以做什么来终止群组(或者,在群组术语中,AggregatorActor
)?
答案 0 :(得分:0)
我所做的是将AggregatorActor
更改为wait_for_results
:
class AggregatorActor
include Celluloid
def initialize(shufflers)
@shufflerset = shufflers
@results = {}
end
def wait_for_results
sleep 5 while not @shufflerset.empty?
self.output
self.terminate
end
def add_result(result)
@results.merge! result
@shufflerset = @shufflerset - result.keys
puts "Results for #{result.keys.inspect} recorded, remaining: #{@shufflerset.inspect}"
end
def output
puts @results
end
end
然后我摆脱了SupervisionGroup
(因为我不需要监督,即重新运行失败的演员),我就这样使用它了:
shufflers = [RubyShuffler, PileShuffle, VariablePileShuffle, VariablePileShuffleHuman, RiffleShuffle].to_set
Celluloid::Actor[:aggregator] = AggregatorActor.new(shufflers.map { |sh| sh.new.name })
shufflers.each do |shuffler|
Celluloid::Actor[shuffler.name.to_sym] = EvalActor.new shuffler
end
Celluloid::Actor[:aggregator].wait_for_results
感觉不是很干净,如果有更清洁的方式会很好,但至少这样可行。