concurrent-ruby icon indicating copy to clipboard operation
concurrent-ruby copied to clipboard

Waiting for Actor termination?

Open mvgijssel opened this issue 6 years ago • 1 comments

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

mvgijssel avatar Sep 18 '19 08:09 mvgijssel

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.

pitr-ch avatar Feb 10 '20 15:02 pitr-ch