concurrent-ruby
concurrent-ruby copied to clipboard
Waiting for Actor termination?
Is there an easy way to wait for an Actor to terminate? I'm aware that I can wait till all messages are processed:
actor = MyActor.spawn(name: 'actor')
actor << :dostuff
actor.ask(:await).wait
or wait for the actor to respond (which AFAIK is the same)
actor = MyActor.spawn(name: 'actor')
actor << :dostuff
actor.ask(:some_result).value # or actor.ask!(:some_result)
but both are not what I'm looking for. I want to know how to block until an actor is terminated when the actor has asynchronous execution itself:
class MyActor < Concurrent::Actor::Context
def on_message(message)
case message
when :start
promises = 10.times.map do |n|
Concurrent::Promises.future do
sleep 1
n
end
end
Concurrent::Promises.zip(*promises).then do
self.tell :terminate!
end
Concurrent::Actor::Behaviour::MESSAGE_PROCESSED
else
pass
end
end
end
my_actor = MyActor.spawn(name: 'actor')
my_actor.tell(:start)
# How to do this, as this is obviously not great:
loop do
break if my_actor.ask!(:terminated?)
end
The newer Actor implementation which has exact same behaviour as Erlang is more thought out in that respect and has http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor/Pid.html#terminated-instance_method
In the old Actors you can either create a different actor and link it or ask for a termination event with :termination_event message. Then you can block with wait on the event.