Class: Concurrent::Actor::Behaviour::Linking — Concurrent Ruby

# Class: Concurrent::Actor::Behaviour::Linking

Inherits:
  Abstract
  - Object
  - Abstract
  - Concurrent::Actor::Behaviour::Linking
  show all

Defined in:
  lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb

## Overview

Links the actor to other actors and sends actor's events to them, like: `:terminated`, `:paused`, `:resumed`, errors, etc. Linked actor needs to handle those messages.

    listener = AdHoc.spawn name: :listener do
      lambda do |message|
        case message
        when Reference
          if message.ask!(:linked?)
            message << :unlink
          else
            message << :link
          end
        else
          puts "got event #{message.inspect} from #{envelope.sender}"
        end
      end
    end

    an_actor = AdHoc.spawn name: :an_actor, supervise: true, behaviour_definition: Behaviour.restarting_behaviour_definition do
      lambda { |message| raise 'failed'}
    end

    # link the actor
    listener.ask(an_actor).wait
    an_actor.ask(:fail).wait
    # unlink the actor
    listener.ask(an_actor).wait
    an_actor.ask(:fail).wait
    an_actor << :terminate!

produces only two events, other events happened after unlinking

    got event #<RuntimeError: failed> from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>
    got event :reset from #<Concurrent::Actor::Reference /an_actor (Concurrent::Actor::Utils::AdHoc)>

## Instance Method Summary collapse

- #initialize(core, subsequent, core_options) ⇒ Linking constructor

  A new instance of Linking.

- #link(ref) ⇒ undocumented
- #on_envelope(envelope) ⇒ undocumented
- #on_event(public, event) ⇒ undocumented
- #unlink(ref) ⇒ undocumented

## Constructor Details

### #initialize(core, subsequent, core_options) ⇒ `Linking`

Returns a new instance of Linking.

    43
    44
    45
    46
    47
    # File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 43

    def initialize(core, subsequent, core_options)
      super core, subsequent, core_options
      @linked = Set.new
      @linked.add Actor.current if core_options[:link] != false
    end

## Instance Method Details

### #link(ref) ⇒ `undocumented`

    64
    65
    66
    67
    # File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 64

    def link(ref)
      @linked.add(ref)
      true
    end

### #on_envelope(envelope) ⇒ `undocumented`

    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    # File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 49

    def on_envelope(envelope)
      case envelope.message
      when :link
        link envelope.sender
      when :unlink
        unlink envelope.sender
      when :linked?
        @linked.include? envelope.sender
      when :linked
        @linked.to_a
      else
        pass envelope
      end
    end

### #on_event(public, event) ⇒ `undocumented`

    74
    75
    76
    77
    78
    79
    # File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 74

    def on_event(public, event)
      event_name, _ = event
      @linked.each { |a| a << event } if public
      @linked.clear if event_name == :terminated
      super public, event
    end

### #unlink(ref) ⇒ `undocumented`

    69
    70
    71
    72
    # File 'lib/concurrent-ruby-edge/concurrent/actor/behaviour/linking.rb', line 69

    def unlink(ref)
      @linked.delete(ref)
      true
    end