123456789_123456789_123456789_123456789_123456789_

Class: Concurrent::Actor::AbstractContext Abstract

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: lib/concurrent-ruby-edge/concurrent/actor/context.rb

Overview

This class is abstract.

New actor is defined by subclassing RestartingContext, Context and defining its abstract methods. AbstractContext can be subclassed directly to implement more specific behaviour see Root implementation.

Example of ac actor definition:

Message = {Struct.new} :action, :value 

class AnActor < {Concurrent::Actor::RestartingContext}
  def initialize(init)
    @counter = init
  end

  # override #on_message to define actor's behaviour on message received
  def on_message(message)
    case message.action
    when :add
      @counter = @counter + message.value
    when :subtract
      @counter = @counter - message.value
    when :value
      @counter
    else
      pass
    end
  end

  # set counter to zero when there is an error
  def on_event(event)
    if event == :reset
      @counter = 0 # ignore initial value
    end
  end
end 

an_actor = {AnActor.spawn} name: 'an_actor', args: 10 
an_actor << {Message.new}(:add, 1) << {Message.new}(:subtract, 2) 
an_actor.ask!(Message.new(:value, nil))            # => 9
an_actor << :boo << {Message.new}(:add, 1) 
an_actor.ask!(Message.new(:value, nil))            # => 1
an_actor << :terminate!
    # => #<Concurrent::Actor::Reference:0x7fbedc137688 /an_actor (AnActor)>

See methods of AbstractContext what else can be tweaked, e.g #default_reference_class

Constant Summary

Concern::Logging - Included

SEV_LABEL

Class Method Summary

Instance Attribute Summary

Instance Method Summary

InternalDelegations - Included

Concern::Logging - Included

#log

Logs through Concurrent.global_logger, it can be overridden by setting @logger.

PublicDelegations - Included

TypeCheck - Included

Class Method Details

.spawn(name_or_opts, *args, &block)

Behaves as Concurrent::Actor.spawn but :class is auto-inserted based on receiver so it can be omitted.

Examples:

by class and name

AdHoc.spawn(:ping1) { -> message { message } }

by option hash

inc2 = AdHoc.spawn(name:     'increment by 2',
                   args:     [2],
                   executor: Concurrent.global_fast_executor) do |increment_by|
  lambda { |number| number + increment_by }
end
inc2.ask!(2) # => 4

See Also:

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 117

def self.spawn(name_or_opts, *args, &block)
  Actor.spawn to_spawn_options(name_or_opts, *args), &block
end

.spawn!(name_or_opts, *args, &block)

behaves as Concurrent::Actor.spawn! but :class is auto-inserted based on receiver so it can be omitted.

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 122

def self.spawn!(name_or_opts, *args, &block)
  Actor.spawn! to_spawn_options(name_or_opts, *args), &block
end

.to_spawn_options(name_or_opts, *args) (private)

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 132

def self.to_spawn_options(name_or_opts, *args)
  if name_or_opts.is_a? ::Hash
    if name_or_opts.key?(:class) && name_or_opts[:class] != self
      raise ArgumentError,
            ':class option is ignored when calling on context class, use Actor.spawn instead'
    end
    name_or_opts.merge class: self
  else
    { class: self, name: name_or_opts, args: args }
  end
end

Instance Attribute Details

#core (readonly)

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 30

attr_reader :core

Instance Method Details

#<<(message)

Alias for #tell.

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 102

alias_method :<<, :tell

#ask(message) Also known as: #ask!

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 98

def ask(message)
  raise 'actor cannot ask itself'
end

#ask!(message)

Alias for #ask.

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 103

alias_method :ask!, :ask

#behaviour_definitionArray<Array(Behavior::Abstract, Array<Object>)>

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 72

def behaviour_definition
  raise NotImplementedError
end

#dead_letter_routingReference

Defines an actor responsible for dead letters. Any rejected message send with Reference#tell is sent there, a message with future is considered already monitored for failures. Default behaviour is to use #dead_letter_routing of the parent, so if no #dead_letter_routing method is overridden in parent-chain the message ends up in Actor.root.dead_letter_routing agent which will log warning.

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 67

def dead_letter_routing
  parent.dead_letter_routing
end

#default_executorExecutor

override to se different default executor, e.g. to change it to global_fast_executor

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 89

def default_executor
  Concurrent.global_io_executor
end

#default_reference_classCLass

override if different class for reference is needed

Returns:

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 83

def default_reference_class
  Reference
end

#envelopeEnvelope

Returns:

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 77

def envelope
  @envelope or raise 'envelope not set'
end

#initialize_core(core) (private)

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 128

def initialize_core(core)
  @core = Type! core, Core
end

#on_envelope(envelope)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 46

def on_envelope(envelope)
  @envelope = envelope
  on_message envelope.message
ensure
  @envelope = nil
end

#on_event(event)

override to add custom code invocation on internal events like :terminated, :resumed, anError.

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 42

def on_event(event)
end

#on_message(message) ⇒ Object

This method is abstract.

override to define Actor’s behaviour

Note:

self should not be returned (or sent to other actors), #reference should be used instead

Parameters:

Returns:

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 37

def on_message(message)
  raise NotImplementedError
end

#pass

if you want to pass the message to next behaviour, usually Behaviour::ErrorsOnUnknownMessage

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 55

def pass
  core.behaviour!(Behaviour::ExecutesContext).pass envelope
end

#tell(message) Also known as: #<<

tell self a message

[ GitHub ]

  
# File 'lib/concurrent-ruby-edge/concurrent/actor/context.rb', line 94

def tell(message)
  reference.tell message
end