Class: Concurrent::ErlangActor::Environment
- Inherits:
-
Synchronization::Object
- Object
- Synchronization::AbstractObject
- Synchronization::Object
- Concurrent::ErlangActor::Environment
- Defined in:
- lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb
Overview
A class providing environment and methods for actor bodies to run in.
Instance Method Summary collapse
-
#default_executor ⇒ ExecutorService
A default executor which is picked by spawn call.
-
#demonitor(reference, *options) ⇒ true, false
If MonitorRef is a reference which the calling actor obtained by calling #monitor, this monitoring is turned off.
-
#link(pid) ⇒ true
Creates a link between the calling actor and another actor, if there is not such a link already.
-
#monitor(pid) ⇒ Reference
The calling actor starts monitoring actor with given pid.
-
#name ⇒ #to_s
The name od the actor if provided to spawn method.
-
#on(matcher, value = nil, &block) ⇒ undocumented
Helper for constructing a #receive rules.
-
#pid ⇒ Pid
The pid of this actor.
-
#receive(*rules, timeout: nil, timeout_value: nil, **options) {|message| ... } ⇒ Object, nothing
Receive a message.
-
#reply(value) ⇒ true, false
Shortcut for fulfilling the reply, same as
reply_resolution true, value, nil
. -
#reply_resolution(fulfilled = true, value = nil, reason = nil) ⇒ true, false
Reply to the sender of the message currently being processed if the actor was asked instead of told.
-
#spawn(*args, type: @Actor.class, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_executor, link: false, monitor: false) {|*args| ... } ⇒ Pid, ::Array(Pid, Reference)
Creates an actor.
-
#terminate(pid = nil, reason, value: nil) ⇒ nothing
If pid is not provided stops the execution of the calling actor with the exit reason.
-
#terminated ⇒ Promises::Future
A future which is resolved with the final result of the actor that is either the reason for termination or a value if terminated normally.
-
#trap(value = true) ⇒ true, false
When trap is set to true, exit signals arriving to a actor are converted to Terminated messages, which can be received as ordinary messages.
-
#traps? ⇒ true, false
Does this actor trap exit messages?.
-
#unlink(pid) ⇒ true
Removes the link, if there is one, between the calling actor and the actor referred to by pid.
Instance Method Details
#default_executor ⇒ ExecutorService
Returns a default executor which is picked by spawn call.
465 466 467 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 465 def default_executor @DefaultExecutor end |
#demonitor(reference, *options) ⇒ true, false
If MonitorRef is a reference which the calling actor obtained by calling #monitor, this monitoring is turned off. If the monitoring is already turned off, nothing happens.
Once demonitor has returned it is guaranteed that no DownSignal message
due to the monitor will be placed in the caller's message queue in the future.
A DownSignal message might have been placed in the caller's message queue prior to the call, though.
Therefore, in most cases, it is advisable to remove such a 'DOWN' message from the message queue
after monitoring has been stopped.
demonitor(reference, :flush)
can be used if this cleanup is wanted.
The behavior of this method can be viewed as two combined operations: asynchronously send a "demonitor signal" to the monitored actor and ignore any future results of the monitor.
Failure: It is an error if reference refers to a monitoring started by another actor. In that case it may raise an ArgumentError or go unnoticed.
Options:
:flush
- Remove (one) DownSignal message, if there is one, from the caller's message queue after monitoring has been stopped. Callingdemonitor(pid, :flush)
is equivalent to the following, but more efficient:demonitor(pid) receive on(And[DownSignal, -> d { d.reference == reference}], true), timeout: 0, timeout_value: true
info
The returned value is one of the following:-
true
- The monitor was found and removed. In this case no DownSignal message due to this monitor have been nor will be placed in the message queue of the caller. -
false
- The monitor was not found and could not be removed. This probably because someone already has placed a DownSignal message corresponding to this monitor in the caller's message queue.
If the info option is combined with the flush option,
false
will be returned if a flush was needed; otherwise,true
.-
332 333 334 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 332 def demonitor(reference, *) @Actor.demonitor(reference, *) end |
#link(pid) ⇒ true
Creates a link between the calling actor and another actor, if there is not such a link already. If a actor attempts to create a link to itself, nothing is done. Returns true.
If pid does not exist, the behavior of the method depends on if the calling actor is trapping exits or not (see #trap):
- If the calling actor is not trapping exits link raises with NoActor.
- Otherwise, if the calling actor is trapping exits, link returns true, but an exit signal with reason noproc is sent to the calling actor.
236 237 238 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 236 def link(pid) @Actor.link(pid) end |
#monitor(pid) ⇒ Reference
The calling actor starts monitoring actor with given pid.
A DownSignal message will be sent to the monitoring actor if the actor with given pid dies, or if the actor with given pid does not exist.
The monitoring is turned off either when the DownSignal message is sent, or when #demonitor is called.
Making several calls to monitor for the same pid is not an error; it results in as many, completely independent, monitorings.
285 286 287 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 285 def monitor(pid) @Actor.monitor(pid) end |
#name ⇒ #to_s
Returns the name od the actor if provided to spawn method.
154 155 156 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 154 def name pid.name end |
#on(matcher, value = nil, &block) ⇒ undocumented
Helper for constructing a #receive rules
185 186 187 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 185 def on(matcher, value = nil, &block) @Actor.on matcher, value, &block end |
#pid ⇒ Pid
Returns the pid of this actor.
149 150 151 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 149 def pid @Actor.pid end |
#receive(*rules, timeout: nil, timeout_value: nil, **options) {|message| ... } ⇒ Object, nothing
Receive a message.
218 219 220 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 218 def receive(*rules, timeout: nil, timeout_value: nil, **, &block) @Actor.receive(*rules, timeout: timeout, timeout_value: timeout_value, **, &block) end |
#reply(value) ⇒ true, false
Shortcut for fulfilling the reply, same as reply_resolution true, value, nil
.
405 406 407 408 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 405 def reply(value) # TODO (pitr-ch 08-Feb-2019): consider adding reply? which returns true,false if success, reply method will always return value reply_resolution true, value, nil end |
#reply_resolution(fulfilled = true, value = nil, reason = nil) ⇒ true, false
Reply to the sender of the message currently being processed if the actor was asked instead of told. The reply is stored in a Promises::ResolvableFuture so the arguments are same as for Promises::ResolvableFuture#resolve method.
The reply may timeout, then this will fail with false.
426 427 428 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 426 def reply_resolution(fulfilled = true, value = nil, reason = nil) @Actor.reply_resolution(fulfilled, value, reason) end |
#spawn(*args, type: @Actor.class, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_executor, link: false, monitor: false) {|*args| ... } ⇒ Pid, ::Array(Pid, Reference)
Creates an actor.
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 378 def spawn(*args, type: @Actor.class, channel: Promises::Channel.new, environment: Environment, name: nil, executor: default_executor, link: false, monitor: false, &body) @Actor.spawn(*args, type: type, channel: channel, environment: environment, name: name, executor: executor, link: link, monitor: monitor, &body) end |
#terminate(pid = nil, reason, value: nil) ⇒ nothing
If pid is not provided stops the execution of the calling actor with the exit reason.
If pid is provided, it sends an exit signal with exit reason to the actor identified by pid.
The following behavior apply
if reason
is any object except :normal
or :kill
.
If pid is not trapping exits,
pid itself will exit with exit reason.
If pid is trapping exits,
the exit signal is transformed into a message Terminated
and delivered to the message queue of pid.
If reason is the Symbol :normal
, pid will not exit.
If it is trapping exits, the exit signal is transformed into a message Terminated
and delivered to its message queue.
If reason is the Symbol :kill
, that is if exit(pid, :kill)
is called,
an untrappable exit signal is sent to pid which will unconditionally exit
with exit reason :killed
.
Since evaluating this function causes the process to terminate, it has no return value.
460 461 462 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 460 def terminate(pid = nil, reason, value: nil) @Actor.terminate pid, reason, value: value end |
#terminated ⇒ Promises::Future
Returns a future which is resolved with the final result of the actor that is either the reason for termination or a value if terminated normally.
144 145 146 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 144 def terminated @Actor.terminated end |
#trap(value = true) ⇒ true, false
When trap is set to true, exit signals arriving to a actor are converted to Terminated messages, which can be received as ordinary messages. If trap is set to false, the actor exits if it receives an exit signal other than normal and the exit signal is propagated to its linked actors. Application actors should normally not trap exits.
176 177 178 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 176 def trap(value = true) @Actor.trap(value) end |
#traps? ⇒ true, false
Returns does this actor trap exit messages?.
160 161 162 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 160 def traps? @Actor.traps? end |
#unlink(pid) ⇒ true
Removes the link, if there is one, between the calling actor and the actor referred to by pid.
Returns true and does not fail, even if there is no link to Id, or if Id does not exist.
Once unlink(pid) has returned it is guaranteed that the link between the caller and the actor referred to by pid has no effect on the caller in the future (unless the link is setup again). If caller is trapping exits, an Terminated message due to the link might have been placed in the caller's message queue prior to the call, though.
Note, the Terminated message can be the result of the link, but can also be the result of calling #terminate method externally. Therefore, it may be appropriate to cleanup the message queue when trapping exits after the call to unlink, as follow:
receive on(And[Terminated, -> e { e.pid == pid }], true), timeout: 0
262 263 264 |
# File 'lib/concurrent-ruby-edge/concurrent/edge/erlang_actor.rb', line 262 def unlink(pid) @Actor.unlink(pid) end |