I am implementing a simple program in Celluloid that ideally will run a few actors in parallel, each of which will compute something, and then send its result back to a main actor, whose job is simply to aggregate results.
Following this FAQ, I introduced a SupervisionGroup
, like this:
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
I terminate the EvalActor
s after they're done, and I also terminate the AggregatorActor
when all of the workers are done.
However, the supervision thread stays alive and keeps the main thread alive. The program never terminates.
If I send .run!
to the group, then the main thread terminates right after it, and nothing works.
What can I do to terminate the group (or, in group terminology, finalize
, I suppose) after the AggregatorActor
terminates?