Class: Concurrent::Actor::AbstractContext Abstract

Inherits:
Object
  • Object
show all
Includes:
InternalDelegations, TypeCheck
Defined in:
lib-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!
    # => #

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

Direct Known Subclasses

Context, RestartingContext, Root

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#coreundocumented (readonly)



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

def core
  @core
end

Class Method Details

.spawn(name_or_opts, *args, &block) ⇒ undocumented

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.configuration.global_task_pool) do |increment_by|
  lambda { |number| number + increment_by }
end
inc2.ask!(2) # => 4

See Also:



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

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) ⇒ undocumented

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



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

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

Instance Method Details

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



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

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

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

Returns:

Raises:

  • (NotImplementedError)


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

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.

Returns:



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

def dead_letter_routing
  parent.dead_letter_routing
end

#default_executorExecutor

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

Returns:

  • (Executor)


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

def default_executor
  Concurrent.global_io_executor
end

#default_reference_classCLass

override if different class for reference is needed

Returns:



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

def default_reference_class
  Reference
end

#envelopeEnvelope

Returns current envelope, accessible inside #on_message processing.

Returns:

  • (Envelope)

    current envelope, accessible inside #on_message processing



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

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

#on_envelope(envelope) ⇒ undocumented

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



44
45
46
47
48
49
# File 'lib-edge/concurrent/actor/context.rb', line 44

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

#on_event(event) ⇒ undocumented

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



40
41
# File 'lib-edge/concurrent/actor/context.rb', line 40

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), PublicDelegations#reference should be used instead

Returns a result which will be used to set the Future supplied to Reference#ask.

Parameters:

  • message (Object)

Returns:

  • (Object)

    a result which will be used to set the Future supplied to Reference#ask

Raises:

  • (NotImplementedError)


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

def on_message(message)
  raise NotImplementedError
end

#passundocumented

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



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

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

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

tell self a message



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

def tell(message)
  reference.tell message
end

#behaviour(behaviour_class) ⇒ undocumented Originally defined in module InternalDelegations

see Core#behaviour

#behaviour!(behaviour_class) ⇒ undocumented Originally defined in module InternalDelegations

see Core#behaviour!

#Child!(value, *types) ⇒ undocumented Originally defined in module TypeCheck

#Child?(value, *types) ⇒ Boolean Originally defined in module TypeCheck

Returns:

  • (Boolean)

#childrenundocumented Originally defined in module InternalDelegations

See Also:

#contextAbstractContext Originally defined in module InternalDelegations

Returns:

#context_classundocumented Also known as: actor_class Originally defined in module PublicDelegations

See Also:

#executorundocumented Originally defined in module PublicDelegations

See Also:

#log(level, message = nil, &block) ⇒ undocumented Originally defined in module InternalDelegations

delegates to core.log

See Also:

  • Logging#log

#Match!(value, *types) ⇒ undocumented Originally defined in module TypeCheck

#Match?(value, *types) ⇒ Boolean Originally defined in module TypeCheck

Returns:

  • (Boolean)

#nameundocumented Originally defined in module PublicDelegations

See Also:

#parentundocumented Originally defined in module PublicDelegations

See Also:

#pathundocumented Originally defined in module PublicDelegations

See Also:

#redirect(reference, envelope = self.envelope) ⇒ undocumented Originally defined in module InternalDelegations

#referenceundocumented Also known as: ref Originally defined in module PublicDelegations

See Also:

#terminate!(reason = nil) ⇒ undocumented Originally defined in module InternalDelegations

See Also:

  • Termination#terminate!

#terminated?Boolean Originally defined in module InternalDelegations

Returns:

  • (Boolean)

See Also:

  • Termination#terminated?

#Type!(value, *types) ⇒ undocumented Originally defined in module TypeCheck

#Type?(value, *types) ⇒ Boolean Originally defined in module TypeCheck

Returns:

  • (Boolean)