• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ruby-concurrency / concurrent-ruby / #2764

08 Dec 2014 03:40PM UTC coverage: 91.388% (-0.4%) from 91.753%
#2764

push

jdantonio
Merge pull request #201 from rkday/fallback_handling

Posting to a shutdown thread pool - JRuby consistency and better naming

18 of 26 new or added lines in 5 files covered. (69.23%)

212 existing lines in 36 files now uncovered.

2812 of 3077 relevant lines covered (91.39%)

369.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.0
/lib/concurrent/actor/context.rb
1
module Concurrent
1✔
2
  module Actor
1✔
3

4
    # Abstract implementation of Actor context. Children has to implement
5
    # {AbstractContext#on_message} and {AbstractContext#behaviour_definition} methods.
6
    # There are two implementations:
7
    #
8
    # -   {Context}
9
    #
10
    #     > {include:Actor::Context}
11
    #
12
    # -   {RestartingContext}.
13
    #
14
    #     > {include:Actor::RestartingContext}
15
    class AbstractContext
1✔
16
      include TypeCheck
1✔
17
      include InternalDelegations
1✔
18

19
      attr_reader :core
1✔
20

21
      # @abstract override to define Actor's behaviour
22
      # @param [Object] message
23
      # @return [Object] a result which will be used to set the IVar supplied to Reference#ask
24
      # @note self should not be returned (or sent to other actors), {#reference} should be used
25
      #   instead
26
      def on_message(message)
1✔
UNCOV
27
        raise NotImplementedError
×
28
      end
29

30
      # override to add custom code invocation on events like `:terminated`, `:resumed`, `anError`.
31
      def on_event(event)
1✔
32
      end
33

34
      # @api private
35
      def on_envelope(envelope)
1✔
36
        @envelope = envelope
689✔
37
        on_message envelope.message
689✔
38
      ensure
39
        @envelope = nil
689✔
40
      end
41

42
      # if you want to pass the message to next behaviour, usually {Behaviour::ErrorsOnUnknownMessage}
43
      def pass
1✔
44
        core.behaviour!(Behaviour::ExecutesContext).pass envelope
3✔
45
      end
46

47
      # Defines an actor responsible for dead letters. Any rejected message send with
48
      # {Reference#tell} is sent there, a message with ivar is considered already monitored for
49
      # failures. Default behaviour is to use {AbstractContext#dead_letter_routing} of the parent,
50
      # so if no {AbstractContext#dead_letter_routing} method is overridden in parent-chain the message ends up in
51
      # `Actor.root.dead_letter_routing` agent which will log warning.
52
      # @return [Reference]
53
      def dead_letter_routing
1✔
54
        parent.dead_letter_routing
10✔
55
      end
56

57
      # @return [Array<Array(Behavior::Abstract, Array<Object>)>]
58
      def behaviour_definition
1✔
UNCOV
59
        raise NotImplementedError
×
60
      end
61

62
      # @return [Envelope] current envelope, accessible inside #on_message processing
63
      def envelope
1✔
64
        @envelope or raise 'envelope not set'
15✔
65
      end
66

67
      # override if different class for reference is needed
68
      # @return [CLass] descendant of {Reference}
69
      def default_reference_class
1✔
70
        Reference
255✔
71
      end
72

73
      def tell(message)
1✔
UNCOV
74
        reference.tell message
×
75
      end
76

77
      def ask(message)
1✔
UNCOV
78
        raise 'actor cannot ask itself'
×
79
      end
80

81
      alias_method :<<, :tell
1✔
82
      alias_method :ask!, :ask
1✔
83

84
      private
1✔
85

86
      def initialize_core(core)
1✔
87
        @core = Type! core, Core
257✔
88
      end
89

90
      # behaves as {Concurrent::Actor.spawn} but :class is auto-inserted based on receiver
91
      def self.spawn(name_or_opts, *args, &block)
1✔
92
        Actor.spawn spawn_optionify(name_or_opts, *args), &block
237✔
93
      end
94

95
      # behaves as {Concurrent::Actor.spawn!} but :class is auto-inserted based on receiver
96
      def self.spawn!(name_or_opts, *args, &block)
1✔
97
        Actor.spawn! spawn_optionify(name_or_opts, *args), &block
5✔
98
      end
99

100
      private
1✔
101

102
      def self.spawn_optionify(name_or_opts, *args)
1✔
103
        if name_or_opts.is_a? Hash
242✔
104
          if name_or_opts.key?(:class) && name_or_opts[:class] != self
23✔
105
            raise ArgumentError,
×
106
                  ':class option is ignored when calling on context class, use Actor.spawn instead'
107
          end
108
          name_or_opts.merge class: self
23✔
109
        else
110
          { class: self, name: name_or_opts, args: args }
219✔
111
        end
112
      end
113

114
      # to avoid confusion with Kernel.spawn
115
      undef_method :spawn
1✔
116
    end
117

118
    # Basic Context of an Actor. It does not support supervision and pausing.
119
    # It simply terminates on error.
120
    #
121
    # -   linking
122
    # -   terminates on error
123
    #
124
    # TODO describe behaviour
125
    # TODO usage
126
    # @example ping
127
    #   class Ping < Context
128
    #     def on_message(message)
129
    #       message
130
    #     end
131
    #   end
132
    #
133
    #   Ping.spawn(:ping1).ask(:m).value #=> :m
134
    class Context < AbstractContext
1✔
135
      def behaviour_definition
1✔
136
        Behaviour.basic_behaviour_definition
240✔
137
      end
138
    end
139

140
    # Context of an Actor for complex robust systems.
141
    #
142
    # -   linking
143
    # -   supervising
144
    # -   pauses on error
145
    #
146
    # TODO describe behaviour
147
    # TODO usage
148
    class RestartingContext < AbstractContext
1✔
149
      def behaviour_definition
1✔
150
        Behaviour.restarting_behaviour_definition
8✔
151
      end
152
    end
153
  end
154
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc