# Class: Concurrent::Actor::Behaviour::Termination

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

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

## Overview

Note:

Actor rejects envelopes when terminated.

Note:

TODO missing example

Handles actor termination. Waits until all its children are terminated, can be configured on behaviour initialization.

## Instance Attribute Summary collapse

- #terminated ⇒ undocumented readonly

## Instance Method Summary collapse

- #initialize(core, subsequent, core_options, trapping = false, terminate_children = true) ⇒ Termination constructor

  A new instance of Termination.

- #on_envelope(envelope) ⇒ undocumented
- #terminate!(reason = nil, envelope = nil) ⇒ undocumented

  Terminates the actor.

- #terminated? ⇒ true, false

  If actor is terminated.

- #trapping=(val) ⇒ undocumented
- #trapping? ⇒ Boolean

## Constructor Details

### #initialize(core, subsequent, core_options, trapping = false, terminate_children = true) ⇒ `Termination`

Returns a new instance of Termination

    15
    16
    17
    18
    19
    20
    21

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 15

    def initialize(core, subsequent, core_options, trapping = false, terminate_children = true)
      super core, subsequent, core_options
      @terminated         = Concurrent::Promises.resolvable_future
      @public_terminated  = @terminated.with_hidden_resolvable
      @trapping           = trapping
      @terminate_children = terminate_children
    end

## Instance Attribute Details

### #terminated ⇒ `undocumented` (readonly)

    13
    14
    15

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 13

    def terminated
      @terminated
    end

## Instance Method Details

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

    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 37

    def on_envelope(envelope)
      command, reason = envelope.message
      case command
      when :terminated?
        terminated?
      when :terminate!
        if trapping? && reason != :kill
          pass envelope
        else
          terminate! reason, envelope
        end
      when :termination_event
        @public_terminated
      else
        if terminated?
          reject_envelope envelope
          MESSAGE_PROCESSED
        else
          pass envelope
        end
      end
    end

### #terminate!(reason = nil, envelope = nil) ⇒ `undocumented`

Terminates the actor. Any Envelope received after termination is rejected. Terminates all its children, does not wait until they are terminated.

    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 62

    def terminate!(reason = nil, envelope = nil)
      return true if terminated?

      self_termination = Concurrent::Promises.resolved_future(reason.nil?, reason.nil? || nil, reason)
      all_terminations = if @terminate_children
                           Concurrent::Promises.zip(*children.map { |ch| ch.ask(:terminate!) }, self_termination)
                         else
                           self_termination
                         end

      all_terminations.chain_resolvable(@terminated)
      if envelope && envelope.future
        all_terminations.chain { |fulfilled, _, t_reason| envelope.future.resolve fulfilled, true, t_reason }
      end

      broadcast(true, [:terminated, reason]) # TODO do not end up in Dead Letter Router
      parent << :remove_child if parent

      MESSAGE_PROCESSED
    end

### #terminated? ⇒ `true`, `false`

Note:

Actor rejects envelopes when terminated.

Returns if actor is terminated

Returns:

- (`true`, `false`) —

  if actor is terminated

    25
    26
    27

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 25

    def terminated?
      @terminated.resolved?
    end

### #trapping=(val) ⇒ `undocumented`

    33
    34
    35

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 33

    def trapping=(val)
      @trapping = !!val
    end

### #trapping? ⇒ `Boolean`

Returns:

- (`Boolean`)

    29
    30
    31

    # File 'lib-edge/concurrent/actor/behaviour/termination.rb', line 29

    def trapping?
      @trapping
    end