concurrent-ruby 0.8.0 → 0.9.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +97 -2
  3. data/README.md +103 -54
  4. data/lib/concurrent.rb +34 -14
  5. data/lib/concurrent/async.rb +164 -50
  6. data/lib/concurrent/atom.rb +171 -0
  7. data/lib/concurrent/atomic/atomic_boolean.rb +57 -107
  8. data/lib/concurrent/atomic/atomic_fixnum.rb +73 -101
  9. data/lib/concurrent/atomic/atomic_reference.rb +49 -0
  10. data/lib/concurrent/atomic/condition.rb +23 -12
  11. data/lib/concurrent/atomic/count_down_latch.rb +23 -21
  12. data/lib/concurrent/atomic/cyclic_barrier.rb +47 -47
  13. data/lib/concurrent/atomic/event.rb +33 -42
  14. data/lib/concurrent/atomic/read_write_lock.rb +252 -0
  15. data/lib/concurrent/atomic/semaphore.rb +64 -89
  16. data/lib/concurrent/atomic/thread_local_var.rb +130 -58
  17. data/lib/concurrent/atomic/thread_local_var/weak_key_map.rb +236 -0
  18. data/lib/concurrent/atomic_reference/direct_update.rb +3 -0
  19. data/lib/concurrent/atomic_reference/jruby.rb +6 -3
  20. data/lib/concurrent/atomic_reference/mutex_atomic.rb +10 -32
  21. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +3 -0
  22. data/lib/concurrent/atomic_reference/rbx.rb +4 -1
  23. data/lib/concurrent/atomic_reference/ruby.rb +6 -3
  24. data/lib/concurrent/atomics.rb +74 -4
  25. data/lib/concurrent/collection/copy_on_notify_observer_set.rb +115 -0
  26. data/lib/concurrent/collection/copy_on_write_observer_set.rb +119 -0
  27. data/lib/concurrent/collection/priority_queue.rb +300 -245
  28. data/lib/concurrent/concern/deprecation.rb +27 -0
  29. data/lib/concurrent/concern/dereferenceable.rb +88 -0
  30. data/lib/concurrent/concern/logging.rb +25 -0
  31. data/lib/concurrent/concern/obligation.rb +228 -0
  32. data/lib/concurrent/concern/observable.rb +85 -0
  33. data/lib/concurrent/configuration.rb +226 -112
  34. data/lib/concurrent/dataflow.rb +2 -3
  35. data/lib/concurrent/delay.rb +141 -50
  36. data/lib/concurrent/edge.rb +30 -0
  37. data/lib/concurrent/errors.rb +10 -0
  38. data/lib/concurrent/exchanger.rb +25 -1
  39. data/lib/concurrent/executor/cached_thread_pool.rb +46 -33
  40. data/lib/concurrent/executor/executor.rb +46 -299
  41. data/lib/concurrent/executor/executor_service.rb +521 -0
  42. data/lib/concurrent/executor/fixed_thread_pool.rb +206 -26
  43. data/lib/concurrent/executor/immediate_executor.rb +9 -9
  44. data/lib/concurrent/executor/indirect_immediate_executor.rb +4 -3
  45. data/lib/concurrent/executor/java_cached_thread_pool.rb +18 -16
  46. data/lib/concurrent/executor/java_fixed_thread_pool.rb +11 -18
  47. data/lib/concurrent/executor/java_single_thread_executor.rb +17 -16
  48. data/lib/concurrent/executor/java_thread_pool_executor.rb +55 -102
  49. data/lib/concurrent/executor/ruby_cached_thread_pool.rb +9 -18
  50. data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +10 -21
  51. data/lib/concurrent/executor/ruby_single_thread_executor.rb +14 -16
  52. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +250 -166
  53. data/lib/concurrent/executor/safe_task_executor.rb +5 -4
  54. data/lib/concurrent/executor/serialized_execution.rb +22 -18
  55. data/lib/concurrent/executor/{per_thread_executor.rb → simple_executor_service.rb} +29 -20
  56. data/lib/concurrent/executor/single_thread_executor.rb +32 -21
  57. data/lib/concurrent/executor/thread_pool_executor.rb +72 -60
  58. data/lib/concurrent/executor/timer_set.rb +96 -84
  59. data/lib/concurrent/executors.rb +1 -1
  60. data/lib/concurrent/future.rb +70 -38
  61. data/lib/concurrent/immutable_struct.rb +89 -0
  62. data/lib/concurrent/ivar.rb +152 -60
  63. data/lib/concurrent/lazy_register.rb +40 -20
  64. data/lib/concurrent/maybe.rb +226 -0
  65. data/lib/concurrent/mutable_struct.rb +227 -0
  66. data/lib/concurrent/mvar.rb +44 -43
  67. data/lib/concurrent/promise.rb +208 -134
  68. data/lib/concurrent/scheduled_task.rb +339 -43
  69. data/lib/concurrent/settable_struct.rb +127 -0
  70. data/lib/concurrent/synchronization.rb +17 -0
  71. data/lib/concurrent/synchronization/abstract_object.rb +163 -0
  72. data/lib/concurrent/synchronization/abstract_struct.rb +158 -0
  73. data/lib/concurrent/synchronization/condition.rb +53 -0
  74. data/lib/concurrent/synchronization/java_object.rb +35 -0
  75. data/lib/concurrent/synchronization/lock.rb +32 -0
  76. data/lib/concurrent/synchronization/monitor_object.rb +24 -0
  77. data/lib/concurrent/synchronization/mutex_object.rb +43 -0
  78. data/lib/concurrent/synchronization/object.rb +78 -0
  79. data/lib/concurrent/synchronization/rbx_object.rb +75 -0
  80. data/lib/concurrent/timer_task.rb +87 -100
  81. data/lib/concurrent/tvar.rb +42 -38
  82. data/lib/concurrent/utilities.rb +3 -1
  83. data/lib/concurrent/utility/at_exit.rb +97 -0
  84. data/lib/concurrent/utility/engine.rb +40 -0
  85. data/lib/concurrent/utility/monotonic_time.rb +59 -0
  86. data/lib/concurrent/utility/native_extension_loader.rb +56 -0
  87. data/lib/concurrent/utility/processor_counter.rb +156 -0
  88. data/lib/concurrent/utility/timeout.rb +18 -14
  89. data/lib/concurrent/utility/timer.rb +11 -6
  90. data/lib/concurrent/version.rb +2 -1
  91. data/lib/concurrent_ruby.rb +1 -0
  92. metadata +47 -83
  93. data/lib/concurrent/actor.rb +0 -103
  94. data/lib/concurrent/actor/behaviour.rb +0 -70
  95. data/lib/concurrent/actor/behaviour/abstract.rb +0 -48
  96. data/lib/concurrent/actor/behaviour/awaits.rb +0 -21
  97. data/lib/concurrent/actor/behaviour/buffer.rb +0 -54
  98. data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +0 -12
  99. data/lib/concurrent/actor/behaviour/executes_context.rb +0 -18
  100. data/lib/concurrent/actor/behaviour/linking.rb +0 -45
  101. data/lib/concurrent/actor/behaviour/pausing.rb +0 -77
  102. data/lib/concurrent/actor/behaviour/removes_child.rb +0 -16
  103. data/lib/concurrent/actor/behaviour/sets_results.rb +0 -36
  104. data/lib/concurrent/actor/behaviour/supervised.rb +0 -59
  105. data/lib/concurrent/actor/behaviour/supervising.rb +0 -34
  106. data/lib/concurrent/actor/behaviour/terminates_children.rb +0 -13
  107. data/lib/concurrent/actor/behaviour/termination.rb +0 -54
  108. data/lib/concurrent/actor/context.rb +0 -154
  109. data/lib/concurrent/actor/core.rb +0 -217
  110. data/lib/concurrent/actor/default_dead_letter_handler.rb +0 -9
  111. data/lib/concurrent/actor/envelope.rb +0 -41
  112. data/lib/concurrent/actor/errors.rb +0 -27
  113. data/lib/concurrent/actor/internal_delegations.rb +0 -49
  114. data/lib/concurrent/actor/public_delegations.rb +0 -40
  115. data/lib/concurrent/actor/reference.rb +0 -81
  116. data/lib/concurrent/actor/root.rb +0 -37
  117. data/lib/concurrent/actor/type_check.rb +0 -48
  118. data/lib/concurrent/actor/utils.rb +0 -10
  119. data/lib/concurrent/actor/utils/ad_hoc.rb +0 -21
  120. data/lib/concurrent/actor/utils/balancer.rb +0 -42
  121. data/lib/concurrent/actor/utils/broadcast.rb +0 -52
  122. data/lib/concurrent/actor/utils/pool.rb +0 -59
  123. data/lib/concurrent/actress.rb +0 -3
  124. data/lib/concurrent/agent.rb +0 -209
  125. data/lib/concurrent/atomic.rb +0 -92
  126. data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +0 -118
  127. data/lib/concurrent/atomic/copy_on_write_observer_set.rb +0 -117
  128. data/lib/concurrent/atomic/synchronization.rb +0 -51
  129. data/lib/concurrent/channel/buffered_channel.rb +0 -85
  130. data/lib/concurrent/channel/channel.rb +0 -41
  131. data/lib/concurrent/channel/unbuffered_channel.rb +0 -35
  132. data/lib/concurrent/channel/waitable_list.rb +0 -40
  133. data/lib/concurrent/channels.rb +0 -5
  134. data/lib/concurrent/collection/blocking_ring_buffer.rb +0 -71
  135. data/lib/concurrent/collection/ring_buffer.rb +0 -59
  136. data/lib/concurrent/collections.rb +0 -3
  137. data/lib/concurrent/dereferenceable.rb +0 -108
  138. data/lib/concurrent/executor/ruby_thread_pool_worker.rb +0 -73
  139. data/lib/concurrent/logging.rb +0 -20
  140. data/lib/concurrent/obligation.rb +0 -171
  141. data/lib/concurrent/observable.rb +0 -73
  142. data/lib/concurrent/options_parser.rb +0 -52
  143. data/lib/concurrent/utility/processor_count.rb +0 -152
  144. data/lib/extension_helper.rb +0 -37
@@ -1,54 +0,0 @@
1
- module Concurrent
2
- module Actor
3
- module Behaviour
4
-
5
- # Handles actor termination.
6
- # @note Actor rejects envelopes when terminated.
7
- class Termination < Abstract
8
-
9
- # @!attribute [r] terminated
10
- # @return [Event] event which will become set when actor is terminated.
11
- attr_reader :terminated
12
-
13
- def initialize(core, subsequent)
14
- super core, subsequent
15
- @terminated = Event.new
16
- end
17
-
18
- # @note Actor rejects envelopes when terminated.
19
- # @return [true, false] if actor is terminated
20
- def terminated?
21
- @terminated.set?
22
- end
23
-
24
- def on_envelope(envelope)
25
- case envelope.message
26
- when :terminated?
27
- terminated?
28
- when :terminate!
29
- terminate!
30
- when :terminated_event
31
- terminated
32
- else
33
- if terminated?
34
- reject_envelope envelope
35
- MESSAGE_PROCESSED
36
- else
37
- pass envelope
38
- end
39
- end
40
- end
41
-
42
- # Terminates the actor. Any Envelope received after termination is rejected.
43
- # Terminates all its children, does not wait until they are terminated.
44
- def terminate!
45
- return true if terminated?
46
- terminated.set
47
- broadcast(:terminated) # TODO do not end up in Dead Letter Router
48
- parent << :remove_child if parent
49
- true
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,154 +0,0 @@
1
- module Concurrent
2
- module Actor
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
16
- include TypeCheck
17
- include InternalDelegations
18
-
19
- attr_reader :core
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)
27
- raise NotImplementedError
28
- end
29
-
30
- # override to add custom code invocation on events like `:terminated`, `:resumed`, `anError`.
31
- def on_event(event)
32
- end
33
-
34
- # @api private
35
- def on_envelope(envelope)
36
- @envelope = envelope
37
- on_message envelope.message
38
- ensure
39
- @envelope = nil
40
- end
41
-
42
- # if you want to pass the message to next behaviour, usually {Behaviour::ErrorsOnUnknownMessage}
43
- def pass
44
- core.behaviour!(Behaviour::ExecutesContext).pass envelope
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
54
- parent.dead_letter_routing
55
- end
56
-
57
- # @return [Array<Array(Behavior::Abstract, Array<Object>)>]
58
- def behaviour_definition
59
- raise NotImplementedError
60
- end
61
-
62
- # @return [Envelope] current envelope, accessible inside #on_message processing
63
- def envelope
64
- @envelope or raise 'envelope not set'
65
- end
66
-
67
- # override if different class for reference is needed
68
- # @return [CLass] descendant of {Reference}
69
- def default_reference_class
70
- Reference
71
- end
72
-
73
- def tell(message)
74
- reference.tell message
75
- end
76
-
77
- def ask(message)
78
- raise 'actor cannot ask itself'
79
- end
80
-
81
- alias_method :<<, :tell
82
- alias_method :ask!, :ask
83
-
84
- private
85
-
86
- def initialize_core(core)
87
- @core = Type! core, Core
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)
92
- Actor.spawn spawn_optionify(name_or_opts, *args), &block
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)
97
- Actor.spawn! spawn_optionify(name_or_opts, *args), &block
98
- end
99
-
100
- private
101
-
102
- def self.spawn_optionify(name_or_opts, *args)
103
- if name_or_opts.is_a? Hash
104
- if name_or_opts.key?(:class) && name_or_opts[:class] != self
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
109
- else
110
- { class: self, name: name_or_opts, args: args }
111
- end
112
- end
113
-
114
- # to avoid confusion with Kernel.spawn
115
- undef_method :spawn
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
135
- def behaviour_definition
136
- Behaviour.basic_behaviour_definition
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
149
- def behaviour_definition
150
- Behaviour.restarting_behaviour_definition
151
- end
152
- end
153
- end
154
- end
@@ -1,217 +0,0 @@
1
- module Concurrent
2
- module Actor
3
-
4
- require 'set'
5
-
6
- # Core of the actor
7
- # @note Whole class should be considered private. An user should use {Context}s and {Reference}s only.
8
- # @note devel: core should not block on anything, e.g. it cannot wait on children to terminate
9
- # that would eat up all threads in task pool and deadlock
10
- class Core
11
- include TypeCheck
12
- include Concurrent::Logging
13
- include Synchronization
14
-
15
- # @!attribute [r] reference
16
- # @return [Reference] reference to this actor which can be safely passed around
17
- # @!attribute [r] name
18
- # @return [String] the name of this instance, it should be uniq (not enforced right now)
19
- # @!attribute [r] path
20
- # @return [String] a path of this actor. It is used for easier orientation and logging.
21
- # Path is constructed recursively with: `parent.path + self.name` up to a {Actor.root},
22
- # e.g. `/an_actor/its_child`.
23
- # (It will also probably form a supervision path (failures will be reported up to parents)
24
- # in future versions.)
25
- # @!attribute [r] executor
26
- # @return [Executor] which is used to process messages
27
- # @!attribute [r] actor_class
28
- # @return [Context] a class including {Context} representing Actor's behaviour
29
- attr_reader :reference, :name, :path, :executor, :context_class, :context, :behaviour_definition
30
-
31
- # @option opts [String] name
32
- # @option opts [Reference, nil] parent of an actor spawning this one
33
- # @option opts [Class] reference a custom descendant of {Reference} to use
34
- # @option opts [Context] actor_class a class to be instantiated defining Actor's behaviour
35
- # @option opts [Array<Object>] args arguments for actor_class instantiation
36
- # @option opts [Executor] executor, default is `Concurrent.configuration.global_task_pool`
37
- # @option opts [true, false] link, atomically link the actor to its parent
38
- # @option opts [true, false] supervise, atomically supervise the actor by its parent
39
- # @option opts [Array<Array(Behavior::Abstract, Array<Object>)>] behaviour_definition, array of pairs
40
- # where each pair is behaviour class and its args, see {Behaviour.basic_behaviour_definition}
41
- # @option opts [IVar, nil] initialized, if present it'll be set or failed after {Context} initialization
42
- # @option opts [Proc, nil] logger a proc accepting (level, progname, message = nil, &block) params,
43
- # can be used to hook actor instance to any logging system
44
- # @param [Proc] block for class instantiation
45
- def initialize(opts = {}, &block)
46
- synchronize do
47
- @mailbox = Array.new
48
- @serialized_execution = SerializedExecution.new
49
- @children = Set.new
50
-
51
- @context_class = Child! opts.fetch(:class), AbstractContext
52
- allocate_context
53
-
54
- @executor = Type! opts.fetch(:executor, Concurrent.configuration.global_task_pool), Executor
55
- raise ArgumentError, 'ImmediateExecutor is not supported' if @executor.is_a? ImmediateExecutor
56
-
57
- @reference = (Child! opts[:reference_class] || @context.default_reference_class, Reference).new self
58
- @name = (Type! opts.fetch(:name), String, Symbol).to_s
59
-
60
- parent = opts[:parent]
61
- @parent_core = (Type! parent, Reference, NilClass) && parent.send(:core)
62
- if @parent_core.nil? && @name != '/'
63
- raise 'only root has no parent'
64
- end
65
-
66
- @path = @parent_core ? File.join(@parent_core.path, @name) : @name
67
- @logger = opts[:logger]
68
-
69
- @parent_core.add_child reference if @parent_core
70
-
71
- initialize_behaviours opts
72
-
73
- @args = opts.fetch(:args, [])
74
- @block = block
75
- initialized = Type! opts[:initialized], IVar, NilClass
76
-
77
- messages = []
78
- messages << :link if opts[:link]
79
- messages << :supervise if opts[:supervise]
80
-
81
- schedule_execution do
82
- begin
83
- build_context
84
-
85
- messages.each do |message|
86
- handle_envelope Envelope.new(message, nil, parent, reference)
87
- end
88
-
89
- initialized.set reference if initialized
90
- rescue => ex
91
- log ERROR, ex
92
- @first_behaviour.terminate!
93
- initialized.fail ex if initialized
94
- end
95
- end
96
- end
97
- end
98
-
99
- # @return [Reference, nil] of parent actor
100
- def parent
101
- @parent_core && @parent_core.reference
102
- end
103
-
104
- # @see AbstractContext#dead_letter_routing
105
- def dead_letter_routing
106
- @context.dead_letter_routing
107
- end
108
-
109
- # @return [Array<Reference>] of children actors
110
- def children
111
- guard!
112
- @children.to_a
113
- end
114
-
115
- # @api private
116
- def add_child(child)
117
- guard!
118
- Type! child, Reference
119
- @children.add child
120
- nil
121
- end
122
-
123
- # @api private
124
- def remove_child(child)
125
- guard!
126
- Type! child, Reference
127
- @children.delete child
128
- nil
129
- end
130
-
131
- # is executed by Reference scheduling processing of new messages
132
- # can be called from other alternative Reference implementations
133
- # @param [Envelope] envelope
134
- def on_envelope(envelope)
135
- schedule_execution { handle_envelope envelope }
136
- nil
137
- end
138
-
139
- # ensures that we are inside of the executor
140
- def guard!
141
- unless Actor.current == reference
142
- raise "can be called only inside actor #{reference} but was #{Actor.current}"
143
- end
144
- end
145
-
146
- def log(level, message = nil, &block)
147
- super level, @path, message, &block
148
- end
149
-
150
- # Schedules blocks to be executed on executor sequentially,
151
- # sets Actress.current
152
- def schedule_execution
153
- @serialized_execution.post(@executor) do
154
- synchronize do
155
- begin
156
- Thread.current[:__current_actor__] = reference
157
- yield
158
- rescue => e
159
- log FATAL, e
160
- ensure
161
- Thread.current[:__current_actor__] = nil
162
- end
163
- end
164
- end
165
-
166
- nil
167
- end
168
-
169
- def broadcast(event)
170
- @first_behaviour.on_event(event)
171
- end
172
-
173
- # @param [Class] behaviour_class
174
- # @return [Behaviour::Abstract, nil] based on behaviour_class
175
- def behaviour(behaviour_class)
176
- @behaviours[behaviour_class]
177
- end
178
-
179
- # @param [Class] behaviour_class
180
- # @return [Behaviour::Abstract] based on behaviour_class
181
- # @raise [KeyError] when no behaviour
182
- def behaviour!(behaviour_class)
183
- @behaviours.fetch behaviour_class
184
- end
185
-
186
- # @api private
187
- def allocate_context
188
- @context = @context_class.allocate
189
- end
190
-
191
- # @api private
192
- def build_context
193
- @context.send :initialize_core, self
194
- @context.send :initialize, *@args, &@block
195
- end
196
-
197
- private
198
-
199
- def handle_envelope(envelope)
200
- log DEBUG, "received #{envelope.message.inspect} from #{envelope.sender}"
201
- @first_behaviour.on_envelope envelope
202
- end
203
-
204
- def initialize_behaviours(opts)
205
- @behaviour_definition = (Type! opts[:behaviour_definition] || @context.behaviour_definition, Array).each do |v|
206
- Type! v, Array
207
- Match! v.size, 2
208
- Child! v[0], Behaviour::Abstract
209
- Type! v[1], Array
210
- end
211
- @behaviours = {}
212
- @first_behaviour = @behaviour_definition.reverse.
213
- reduce(nil) { |last, (behaviour, args)| @behaviours[behaviour] = behaviour.new(self, last, *args) }
214
- end
215
- end
216
- end
217
- end
@@ -1,9 +0,0 @@
1
- module Concurrent
2
- module Actor
3
- class DefaultDeadLetterHandler < RestartingContext
4
- def on_message(dead_letter)
5
- log Logging::INFO, "got dead letter #{dead_letter.inspect}"
6
- end
7
- end
8
- end
9
- end
@@ -1,41 +0,0 @@
1
- module Concurrent
2
- module Actor
3
- class Envelope
4
- include TypeCheck
5
-
6
- # @!attribute [r] message
7
- # @return [Object] a message
8
- # @!attribute [r] ivar
9
- # @return [IVar] an ivar which becomes resolved after message is processed
10
- # @!attribute [r] sender
11
- # @return [Reference, Thread] an actor or thread sending the message
12
- # @!attribute [r] address
13
- # @return [Reference] where this message will be delivered
14
-
15
- attr_reader :message, :ivar, :sender, :address
16
-
17
- def initialize(message, ivar, sender, address)
18
- @message = message
19
- @ivar = Type! ivar, IVar, NilClass
20
- @sender = Type! sender, Reference, Thread
21
- @address = Type! address, Reference
22
- end
23
-
24
- def sender_path
25
- if sender.is_a? Reference
26
- sender.path
27
- else
28
- sender.to_s
29
- end
30
- end
31
-
32
- def address_path
33
- address.path
34
- end
35
-
36
- def reject!(error)
37
- ivar.fail error unless ivar.nil?
38
- end
39
- end
40
- end
41
- end
OSZAR »