Class: Concurrent::Actor::Core
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
Concurrent::Synchronization::LockableObject
|
Defined in: | lib/concurrent-ruby-edge/concurrent/actor/core.rb |
Overview
Constant Summary
Concern::Logging
- Included
Class Method Summary
- .new(opts = {}, &block) ⇒ Core constructor
Instance Attribute Summary
-
#actor_class ⇒ Context
readonly
A subclass of
AbstractContext
representing Actor’s behaviour. - #behaviour_definition readonly
- #context readonly
- #context_class readonly
-
#executor ⇒ Executor
readonly
Executor which is used to process messages.
-
#name ⇒ String
readonly
The name of actor instance, it should be uniq (not enforced).
-
#path ⇒ String
readonly
Path of this actor.
-
#reference ⇒ Reference
readonly
Reference
to this actor which can be safely passed around.
Instance Method Summary
- #behaviour(behaviour_class) ⇒ Behaviour::Abstract?
- #behaviour!(behaviour_class) ⇒ Behaviour::Abstract
- #broadcast(public, event)
- #children ⇒ Array<Reference>
- #dead_letter_routing
-
#guard!
ensures that we are inside of the executor.
- #log(level, message = nil, &block)
- #on_envelope(envelope)
-
#parent ⇒ Reference?
A parent
Actor
. -
#schedule_execution
Schedules blocks to be executed on executor sequentially, sets
Actress.current
- #initialize_behaviours(opts) private
- #ns_initialize(opts, &block) private
- #add_child(child) Internal use only Internal use only
- #allocate_context Internal use only Internal use only
- #build_context Internal use only Internal use only
- #process_envelope(envelope) Internal use only Internal use only
- #remove_child(child) Internal use only Internal use only
Concern::Logging
- Included
#log | Logs through Concurrent.global_logger, it can be overridden by setting @logger. |
TypeCheck
- Included
Synchronization::LockableObject
- Inherited
Constructor Details
.new(opts = {}, &block) ⇒ Core
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 50
def initialize(opts = {}, &block) super(&nil) synchronize { ns_initialize(opts, &block) } end
Instance Attribute Details
#actor_class ⇒ Context (readonly)
A subclass of AbstractContext
representing Actor’s behaviour.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
#behaviour_definition (readonly)
[ GitHub ]#context (readonly)
[ GitHub ]# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
#context_class (readonly)
[ GitHub ]
#executor ⇒ Executor
(readonly)
Executor which is used to process messages.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
#name ⇒ String
(readonly)
The name of actor instance, it should be uniq (not enforced). Allows easier orientation between actor instances.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
#path ⇒ String
(readonly)
Path of this actor. It is used for easier orientation and logging. Path is constructed recursively with: parent.path + self.name
up to a Concurrent::Actor.root, e.g. /an_actor/its_child
.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
#reference ⇒ Reference (readonly)
Reference
to this actor which can be safely passed around.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 35
attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
Instance Method Details
#add_child(child)
#allocate_context
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 150
def allocate_context @context = @context_class.allocate end
#behaviour(behaviour_class) ⇒ Behaviour::Abstract?
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 138
def behaviour(behaviour_class) @behaviours[behaviour_class] end
#behaviour!(behaviour_class) ⇒ Behaviour::Abstract
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 145
def behaviour!(behaviour_class) @behaviours.fetch behaviour_class end
#broadcast(public, event)
[ GitHub ]# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 131
def broadcast(public, event) log(DEBUG) { "event: #{event.inspect} (#{public ? 'public' : 'private'})" } @first_behaviour.on_event(public, event) end
#build_context
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 155
def build_context @context.send :initialize_core, self @context.send :initialize, *@args, &@block end
#children ⇒ Array<Reference>
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 68
def children guard! @children.to_a end
#dead_letter_routing
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 63
def dead_letter_routing @context.dead_letter_routing end
#guard!
ensures that we are inside of the executor
#initialize_behaviours(opts) (private)
[ GitHub ]# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 210
def initialize_behaviours(opts) @behaviour_definition = (Type! opts[:behaviour_definition] || @context.behaviour_definition, ::Array).each do |(behaviour, _)| Child! behaviour, Behaviour::Abstract end @behaviours = {} @first_behaviour = @behaviour_definition.reverse. reduce(nil) { |last, (behaviour, *args)| @behaviours[behaviour] = behaviour.new(self, last, opts, *args) } end
#log(level, message = nil, &block)
[ GitHub ]# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 108
def log(level, = nil, &block) super level, @path, , &block end
#ns_initialize(opts, &block) (private)
[ GitHub ]# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 167
def ns_initialize(opts, &block) @mailbox = ::Array.new @serialized_execution = SerializedExecution.new @children = Set.new @context_class = Child! opts.fetch(:class), AbstractContext allocate_context @executor = Type! opts.fetch(:executor, @context.default_executor), Concurrent::AbstractExecutorService @reference = (Child! opts[:reference_class] || @context.default_reference_class, Reference).new self @name = (Type! opts.fetch(:name), String, Symbol).to_s parent = opts[:parent] @parent_core = (Type! parent, Reference, NilClass) && parent.send(:core) if @parent_core.nil? && @name != '/' raise 'only root has no parent' end @path = @parent_core ? File.join(@parent_core.path, @name) : @name @logger = opts[:logger] @parent_core.add_child reference if @parent_core initialize_behaviours opts @args = opts.fetch(:args, []) @block = block initialized = Type! opts[:initialized], Promises::ResolvableFuture, NilClass schedule_execution do begin build_context initialized.fulfill reference if initialized log DEBUG, 'spawned' rescue => ex log ERROR, ex @first_behaviour.terminate! initialized.reject ex if initialized end end end
#on_envelope(envelope)
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 92
def on_envelope(envelope) log(DEBUG) { "is #{envelope.future ? 'asked' : 'told'} #{envelope. .inspect} by #{envelope.sender}" } schedule_execution do log(DEBUG) { "was #{envelope.future ? 'asked' : 'told'} #{envelope. .inspect} by #{envelope.sender} - processing" } process_envelope envelope end nil end
#parent ⇒ Reference?
A parent Actor
. When actor is spawned the Concurrent::Actor.current becomes its parent. When actor is spawned from a thread outside of an actor (Concurrent::Actor.current is nil) Concurrent::Actor.root is assigned.
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 58
def parent @parent_core && @parent_core.reference end
#process_envelope(envelope)
# File 'lib/concurrent-ruby-edge/concurrent/actor/core.rb', line 161
def process_envelope(envelope) @first_behaviour.on_envelope envelope end
#remove_child(child)
#schedule_execution
Schedules blocks to be executed on executor sequentially, sets Actress.current