Class: Thespian::Actor
- Inherits:
-
Object
- Object
- Thespian::Actor
- Defined in:
- lib/thespian/actor.rb
Constant Summary collapse
- STATE_INITIALIZED =
The state an actor is in after it has been created, but before it enters the message processing loop.
:initialized
- STATE_RUNNING =
The state for when an actor is in the message processing loop.
:running
- STATE_FINISHED =
The state for when an actor has exited the message processing loop (either by error or intentially).
:finished
- DEFAULT_OPTIONS =
{ :mode => :thread, :strict => true, :trap_exit => false, :object => nil }
Instance Attribute Summary collapse
-
#exception ⇒ Object
readonly
If an actor died due to an exception, it is stored here.
-
#state ⇒ Object
readonly
Returns the actor’s state.
Instance Method Summary collapse
-
#<<(message) ⇒ Object
Add a message to the actor’s mailbox.
-
#error? ⇒ Boolean
Returns true if an error occurred that caused the actor to enter the :finished state.
-
#finished? ⇒ Boolean
#state == :finished.
-
#initialize(options = {}, &block) ⇒ Actor
constructor
call-seq: new(options = {}){ |message| … }.
-
#initialized? ⇒ Boolean
#state == :initialized.
-
#link(object) ⇒ Object
call-seq: link(actor).
-
#mailbox_size ⇒ Object
Returns how many messages are in the actor’s mailbox.
-
#options(arg = nil) ⇒ Object
call-seq: options -> Hash options(hash) -> Hash options(symbol) -> value.
-
#running? ⇒ Boolean
#state == :running.
-
#salvage_mailbox ⇒ Object
Salvage mailbox contents from a dead actor (including the message it died on).
-
#start ⇒ Object
Start the actor’s message processing loop.
-
#stop ⇒ Object
Stop the actor.
-
#strategy_class ⇒ Object
:nodoc:.
Constructor Details
#initialize(options = {}, &block) ⇒ Actor
call-seq:
new(options = {}){ |message| ... }
Create a new actor using the given block to handles messages. The actor will be in the :initialized
state, meaning the message processing loop hasn’t started yet (see #start).
options
are the same as specified by #options.
42 43 44 45 46 47 48 49 50 |
# File 'lib/thespian/actor.rb', line 42 def initialize( = {}, &block) self.(DEFAULT_OPTIONS.merge()) @state = :initialized @receive_block = block @linked_actors = Set.new @strategy = strategy_class.new{ run } end |
Instance Attribute Details
#exception ⇒ Object (readonly)
If an actor died due to an exception, it is stored here.
11 12 13 |
# File 'lib/thespian/actor.rb', line 11 def exception @exception end |
#state ⇒ Object (readonly)
Returns the actor’s state.
14 15 16 |
# File 'lib/thespian/actor.rb', line 14 def state @state end |
Instance Method Details
#<<(message) ⇒ Object
Add a message to the actor’s mailbox. May raise an exception according to #check_alive!
123 124 125 126 127 128 |
# File 'lib/thespian/actor.rb', line 123 def <<() check_alive! if (:strict) = .new if == Stop @strategy << self end |
#error? ⇒ Boolean
Returns true if an error occurred that caused the actor to enter the :finished state.
156 157 158 |
# File 'lib/thespian/actor.rb', line 156 def error? !!@exception end |
#finished? ⇒ Boolean
#state == :finished
151 152 153 |
# File 'lib/thespian/actor.rb', line 151 def finished? state == :finished end |
#initialized? ⇒ Boolean
#state == :initialized
141 142 143 |
# File 'lib/thespian/actor.rb', line 141 def initialized? state == :initialized end |
#link(object) ⇒ Object
call-seq:
link(actor)
Exceptions in actors will be propogated to actors that are linked to them. How they are propogated is determined by the :trap_exit
option (see #options).
actor
can either be an Actor instance or an instance of a class that included Thespian.
96 97 98 99 100 |
# File 'lib/thespian/actor.rb', line 96 def link(object) actor = object.kind_of?(Actor) ? object : object.actor actor.send(:_link, self) object end |
#mailbox_size ⇒ Object
Returns how many messages are in the actor’s mailbox.
161 162 163 |
# File 'lib/thespian/actor.rb', line 161 def mailbox_size @strategy.mailbox_size end |
#options(arg = nil) ⇒ Object
call-seq:
options -> Hash
options(hash) -> Hash
options(symbol) -> value
Get or set options. Valid options are:
- :mode (default :thread)
-
What mode to create the actor in. Choices are
:fiber
or:thread
. When running in fibered mode, be sure that EventMachine’s reactor is running and there is a root fiber. - :strict (default true)
-
Require an actor to be running in order to put messages into its mailbox.
- :trap_exit (default false)
-
If true, the actor will get a DeadActorError message in its mailbox when a linked actor raises an unhandled exception.
If given no arguments, returns a hash of options.
If given a hash, sets the options specified in the hash.
If given a symbol, returns that option’s value.
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/thespian/actor.rb', line 76 def (arg = nil) @options ||= {} case arg when Hash @options.merge!(arg) when Symbol @options[arg] when nil @options end end |
#running? ⇒ Boolean
#state == :running
146 147 148 |
# File 'lib/thespian/actor.rb', line 146 def running? state == :running end |
#salvage_mailbox ⇒ Object
Salvage mailbox contents from a dead actor (including the message it died on). Useful for restarting a dead actor while preserving its mailbox.
167 168 169 170 171 172 |
# File 'lib/thespian/actor.rb', line 167 def salvage_mailbox raise "cannot salvage mailbox from an actor that isn't finished" unless finished? @strategy..tap do || .unshift(@last_message) if @last_message end end |
#start ⇒ Object
Start the actor’s message processing loop. The thread that the loop is run on is guaranteed to have started by the time this method returns.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/thespian/actor.rb', line 104 def start # Don't let them start an already started actor. raise "already running" if running? # Can't raise an actor from the dead. raise @exception if @exception # IMPORTANT - Race condition! # This method and the thread both set @state. We don't want this method to # possibly overwrite how the thread sets @state, so we set the @state # before staring the thread. @state = :running @strategy.start end |
#stop ⇒ Object
Stop the actor. All pending messages will be processed before stopping the actor. Raises an exception if the actor is not #running? and :strict
(see #options) is true.
133 134 135 136 137 138 |
# File 'lib/thespian/actor.rb', line 133 def stop check_alive! if (:strict) self << Stop.new @strategy.stop raise @exception if @exception end |
#strategy_class ⇒ Object
:nodoc:
52 53 54 55 |
# File 'lib/thespian/actor.rb', line 52 def strategy_class #:nodoc: class_name = [:mode].to_s.capitalize Strategy.const_get(class_name) end |