celluloid 0.18.0.pre → 0.18.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +114 -39
  3. data/CONDUCT.md +13 -0
  4. data/CONTRIBUTING.md +39 -0
  5. data/README.md +59 -55
  6. data/architecture.md +120 -0
  7. data/examples/basic_usage.rb +1 -1
  8. data/examples/configurations.rb +78 -0
  9. data/examples/futures.rb +1 -1
  10. data/examples/ring.rb +5 -4
  11. data/examples/simple_pmap.rb +1 -1
  12. data/examples/stack.rb +2 -2
  13. data/examples/supervisors_and_registry.rb +82 -0
  14. data/examples/timers.rb +1 -1
  15. data/lib/celluloid.rb +72 -47
  16. data/lib/celluloid/actor.rb +27 -17
  17. data/lib/celluloid/actor/system.rb +13 -29
  18. data/lib/celluloid/autostart.rb +5 -5
  19. data/lib/celluloid/backported.rb +6 -2
  20. data/lib/celluloid/call/async.rb +2 -0
  21. data/lib/celluloid/call/sync.rb +10 -3
  22. data/lib/celluloid/calls.rb +5 -12
  23. data/lib/celluloid/cell.rb +5 -9
  24. data/lib/celluloid/condition.rb +3 -3
  25. data/lib/celluloid/core_ext.rb +0 -2
  26. data/lib/celluloid/current.rb +3 -1
  27. data/lib/celluloid/debug.rb +3 -0
  28. data/lib/celluloid/exceptions.rb +2 -2
  29. data/lib/celluloid/future.rb +7 -9
  30. data/lib/celluloid/group.rb +12 -8
  31. data/lib/celluloid/group/pool.rb +1 -3
  32. data/lib/celluloid/group/spawner.rb +2 -6
  33. data/lib/celluloid/internals/call_chain.rb +15 -0
  34. data/lib/celluloid/internals/cpu_counter.rb +62 -0
  35. data/lib/celluloid/internals/handlers.rb +42 -0
  36. data/lib/celluloid/internals/links.rb +38 -0
  37. data/lib/celluloid/internals/logger.rb +104 -0
  38. data/lib/celluloid/internals/method.rb +34 -0
  39. data/lib/celluloid/internals/properties.rb +32 -0
  40. data/lib/celluloid/internals/receivers.rb +64 -0
  41. data/lib/celluloid/internals/registry.rb +102 -0
  42. data/lib/celluloid/internals/responses.rb +46 -0
  43. data/lib/celluloid/internals/signals.rb +24 -0
  44. data/lib/celluloid/internals/stack.rb +74 -0
  45. data/lib/celluloid/internals/stack/dump.rb +12 -0
  46. data/lib/celluloid/internals/stack/states.rb +72 -0
  47. data/lib/celluloid/internals/stack/summary.rb +12 -0
  48. data/lib/celluloid/internals/task_set.rb +51 -0
  49. data/lib/celluloid/internals/thread_handle.rb +52 -0
  50. data/lib/celluloid/internals/uuid.rb +40 -0
  51. data/lib/celluloid/logging/incident.rb +21 -0
  52. data/lib/celluloid/logging/incident_logger.rb +147 -0
  53. data/lib/celluloid/logging/incident_reporter.rb +49 -0
  54. data/lib/celluloid/logging/log_event.rb +20 -0
  55. data/lib/celluloid/logging/ring_buffer.rb +64 -0
  56. data/lib/celluloid/mailbox.rb +22 -9
  57. data/lib/celluloid/mailbox/evented.rb +13 -5
  58. data/lib/celluloid/managed.rb +6 -3
  59. data/lib/celluloid/notifications.rb +95 -0
  60. data/lib/celluloid/pool.rb +6 -0
  61. data/lib/celluloid/probe.rb +81 -0
  62. data/lib/celluloid/proxy/abstract.rb +9 -9
  63. data/lib/celluloid/proxy/async.rb +1 -1
  64. data/lib/celluloid/proxy/block.rb +2 -2
  65. data/lib/celluloid/proxy/cell.rb +1 -1
  66. data/lib/celluloid/proxy/future.rb +2 -4
  67. data/lib/celluloid/proxy/sync.rb +1 -3
  68. data/lib/celluloid/rspec.rb +22 -33
  69. data/lib/celluloid/supervision.rb +17 -0
  70. data/lib/celluloid/supervision/configuration.rb +169 -0
  71. data/lib/celluloid/supervision/configuration/injections.rb +8 -0
  72. data/lib/celluloid/supervision/configuration/instance.rb +113 -0
  73. data/lib/celluloid/supervision/constants.rb +123 -0
  74. data/lib/celluloid/supervision/container.rb +144 -0
  75. data/lib/celluloid/supervision/container/behavior.rb +89 -0
  76. data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
  77. data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
  78. data/lib/celluloid/supervision/container/injections.rb +8 -0
  79. data/lib/celluloid/supervision/container/instance.rb +116 -0
  80. data/lib/celluloid/supervision/container/pool.rb +210 -0
  81. data/{culture/rubocop/perf.yml → lib/celluloid/supervision/container/tree.rb} +0 -0
  82. data/lib/celluloid/supervision/deprecate.rb +9 -0
  83. data/lib/celluloid/supervision/deprecate/supervise.rb +105 -0
  84. data/lib/celluloid/supervision/deprecate/validation.rb +54 -0
  85. data/lib/celluloid/supervision/service.rb +27 -0
  86. data/lib/celluloid/supervision/supervise.rb +34 -0
  87. data/lib/celluloid/supervision/validation.rb +40 -0
  88. data/lib/celluloid/supervision/version.rb +5 -0
  89. data/lib/celluloid/system_events.rb +11 -6
  90. data/lib/celluloid/task.rb +25 -12
  91. data/lib/celluloid/task/fibered.rb +2 -0
  92. data/lib/celluloid/task/threaded.rb +3 -3
  93. data/lib/celluloid/test.rb +5 -2
  94. data/lib/celluloid/thread.rb +0 -2
  95. data/lib/celluloid/version.rb +1 -1
  96. data/spec/celluloid/block_spec.rb +29 -32
  97. data/spec/celluloid/calls_spec.rb +5 -15
  98. data/spec/celluloid/future_spec.rb +2 -2
  99. data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
  100. data/spec/celluloid/internals/links_spec.rb +43 -0
  101. data/spec/celluloid/internals/properties_spec.rb +40 -0
  102. data/spec/celluloid/internals/registry_spec.rb +62 -0
  103. data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
  104. data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
  105. data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
  106. data/spec/celluloid/internals/uuid_spec.rb +9 -0
  107. data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
  108. data/spec/celluloid/mailbox/evented_spec.rb +11 -22
  109. data/spec/celluloid/misc/leak_spec.rb +3 -4
  110. data/spec/celluloid/notifications_spec.rb +140 -0
  111. data/spec/celluloid/probe_spec.rb +102 -0
  112. data/spec/celluloid/proxy_spec.rb +30 -30
  113. data/spec/celluloid/supervision/behavior_spec.rb +74 -0
  114. data/spec/celluloid/supervision/configuration_spec.rb +181 -0
  115. data/spec/celluloid/supervision/container_spec.rb +72 -0
  116. data/spec/celluloid/supervision/instance_spec.rb +13 -0
  117. data/spec/celluloid/supervision/root_spec.rb +28 -0
  118. data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
  119. data/spec/celluloid/task/fibered_spec.rb +1 -3
  120. data/spec/celluloid/task/threaded_spec.rb +1 -3
  121. data/spec/shared/actor_examples.rb +58 -33
  122. data/spec/shared/group_examples.rb +2 -2
  123. data/spec/shared/mailbox_examples.rb +1 -1
  124. data/spec/shared/stack_examples.rb +87 -0
  125. data/spec/shared/task_examples.rb +2 -3
  126. data/spec/spec_helper.rb +2 -4
  127. data/spec/support/configure_rspec.rb +2 -3
  128. data/spec/support/coverage.rb +2 -4
  129. data/spec/support/crash_checking.rb +2 -2
  130. data/spec/support/examples/actor_class.rb +3 -8
  131. data/spec/support/examples/call_class.rb +2 -2
  132. data/spec/support/examples/container_class.rb +35 -0
  133. data/spec/support/examples/evented_mailbox_class.rb +1 -2
  134. data/spec/support/examples/stack_classes.rb +58 -0
  135. data/spec/support/examples/stack_methods.rb +23 -0
  136. data/spec/support/examples/subordinate_class.rb +19 -0
  137. data/spec/support/logging.rb +2 -34
  138. data/spec/support/loose_threads.rb +3 -16
  139. data/spec/support/reset_class_variables.rb +5 -1
  140. data/spec/support/stubbing.rb +1 -1
  141. metadata +91 -316
  142. data/culture/CONDUCT.md +0 -38
  143. data/culture/GSoC/1010-why_we_will_participate.md +0 -17
  144. data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
  145. data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
  146. data/culture/GSoC/1040-getting_students_involved.md +0 -5
  147. data/culture/GSoC/1050-student_involvement_after.md +0 -5
  148. data/culture/GSoC/README.md +0 -16
  149. data/culture/Gemfile +0 -9
  150. data/culture/LICENSE.txt +0 -22
  151. data/culture/README.md +0 -22
  152. data/culture/Rakefile +0 -5
  153. data/culture/SYNC.md +0 -70
  154. data/culture/celluloid-culture.gemspec +0 -18
  155. data/culture/gems/README.md +0 -39
  156. data/culture/gems/dependencies.yml +0 -93
  157. data/culture/gems/loader.rb +0 -101
  158. data/culture/rubocop/README.md +0 -38
  159. data/culture/rubocop/lint.yml +0 -8
  160. data/culture/rubocop/metrics.yml +0 -15
  161. data/culture/rubocop/rubocop.yml +0 -5
  162. data/culture/rubocop/style.yml +0 -61
  163. data/culture/spec/gems_spec.rb +0 -2
  164. data/culture/spec/spec_helper.rb +0 -0
  165. data/culture/spec/sync_spec.rb +0 -2
  166. data/culture/sync.rb +0 -56
  167. data/culture/tasks/rspec.rake +0 -5
  168. data/culture/tasks/rubocop.rake +0 -2
  169. data/lib/celluloid/actor/manager.rb +0 -7
  170. data/lib/celluloid/deprecate.rb +0 -34
  171. data/lib/celluloid/fiber.rb +0 -32
  172. data/lib/celluloid/notices.rb +0 -15
  173. data/spec/deprecate/actor_system_spec.rb +0 -72
  174. data/spec/deprecate/block_spec.rb +0 -52
  175. data/spec/deprecate/calls_spec.rb +0 -39
  176. data/spec/deprecate/evented_mailbox_spec.rb +0 -34
  177. data/spec/deprecate/future_spec.rb +0 -32
  178. data/spec/deprecate/internal_pool_spec.rb +0 -4
  179. data/spec/support/env.rb +0 -21
@@ -0,0 +1,71 @@
1
+ require "set"
2
+
3
+ module Celluloid
4
+ module ClassMethods
5
+ extend Forwardable
6
+ def_delegators :"Celluloid::Supervision::Container::Pool", :pooling_options
7
+ # Create a new pool of workers. Accepts the following options:
8
+ #
9
+ # * size: how many workers to create. Default is worker per CPU core
10
+ # * args: array of arguments to pass when creating a worker
11
+ #
12
+ def pool(config = {}, &block)
13
+ _ = Celluloid.supervise(pooling_options(config, block: block, actors: self))
14
+ _.actors.last
15
+ end
16
+
17
+ # Same as pool, but links to the pool manager
18
+ def pool_link(klass, config = {}, &block)
19
+ Supervision::Container::Pool.new_link(pooling_options(config, block: block, actors: klass))
20
+ end
21
+ end
22
+
23
+ module Supervision
24
+ class Container
25
+ extend Forwardable
26
+ def_delegators :"Celluloid::Supervision::Container::Pool", :pooling_options
27
+
28
+ def pool(klass, config = {}, &block)
29
+ _ = supervise(pooling_options(config, block: block, actors: klass))
30
+ _.actors.last
31
+ end
32
+
33
+ class Instance
34
+ attr_accessor :pool, :pool_size
35
+ end
36
+
37
+ class << self
38
+ # Register a pool of actors to be launched on group startup
39
+ def pool(klass, config, &block)
40
+ blocks << lambda do |container|
41
+ container.pool(klass, config, &block)
42
+ end
43
+ end
44
+ end
45
+
46
+ class Pool
47
+ include Behavior
48
+
49
+ class << self
50
+ def pooling_options(config = {}, mixins = {})
51
+ combined = { type: Celluloid::Supervision::Container::Pool }.merge(config).merge(mixins)
52
+ combined[:args] = [%i[block actors size args].each_with_object({}) do |p, e|
53
+ e[p] = combined.delete(p) if combined[p]
54
+ end]
55
+ combined
56
+ end
57
+ end
58
+
59
+ identifier! :size, :pool
60
+
61
+ configuration do
62
+ @supervisor = Container::Pool
63
+ @method = "pool_link"
64
+ @pool = true
65
+ @pool_size = @configuration[:size]
66
+ @configuration
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,23 @@
1
+ module Celluloid
2
+ module Supervision
3
+ class Container
4
+ class Tree
5
+ include Behavior
6
+
7
+ identifier! :supervises, :supervise
8
+
9
+ configuration do
10
+ if @configuration[:supervise].is_a? Array
11
+ @supervisor = @configuration.dup
12
+ @branch = @configuration.fetch(:branch, @configuration[:as])
13
+ @configuration.delete(Behavior.parameter(:supervise, @configuration))
14
+ elsif @configuration[:supervise].is_a?(Celluloid::Supervision::Configuration)
15
+ @configuration
16
+ else
17
+ raise ArgumentError, "No actors given to Tree to supervise."
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ module Celluloid
2
+ module Supervision
3
+ class Container
4
+ class Injection
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,116 @@
1
+ module Celluloid
2
+ # Supervise collections of actors as a group
3
+ module Supervision
4
+ class Container
5
+ class Instance
6
+ attr_reader :name, :actor
7
+
8
+ # @option options [#call, Object] :args ([]) arguments array for the
9
+ # actor's constructor (lazy evaluation if it responds to #call)
10
+ def initialize(configuration = {})
11
+ @type = configuration.delete(:type)
12
+ @registry = configuration.delete(:registry)
13
+ @branch = configuration.delete(:branch) || :services
14
+ @configuration = configuration
15
+
16
+ # allows injections inside initialize, start, and restart
17
+ @injections = configuration.delete(:injections) || {}
18
+ invoke_injection(:before_initialize)
19
+
20
+ # Stringify keys :/
21
+ # de @configuration = configuration.each_with_object({}) { |(k,v), h| h[k.to_s] = v }
22
+
23
+ @name = @configuration[:as]
24
+ @block = @configuration[:block]
25
+ @args = prepare_args(@configuration[:args])
26
+ @method = @configuration[:method] || "new_link"
27
+ add_accessors
28
+ invoke_injection(:after_initialize)
29
+ start
30
+ end
31
+
32
+ def start
33
+ invoke_injection(:before_start)
34
+ @actor = @type.send(@method, *@args, &@block)
35
+ @registry.add(@name, @actor, @branch) if @name
36
+ invoke_injection(:after_start)
37
+ rescue Celluloid::TaskTimeout => ex
38
+ Internals::Logger.error("TaskTimeout at start of supervised instance of #{@type}")
39
+ raise ex
40
+ # TODO: Implement timeout/retry(?)
41
+ rescue => ex
42
+ Internals::Logger.error("Error ( #{ex.class} ) at start of supervised instance of #{@type}")
43
+ raise ex
44
+ end
45
+
46
+ def restart
47
+ # no need to reset @actor, as this is called in an `exclusive {}` block
48
+ # @actor = nil
49
+ # cleanup
50
+ invoke_injection(:before_restart)
51
+ start
52
+ invoke_injection(:after_restart)
53
+ end
54
+
55
+ def terminate
56
+ @actor.terminate if @actor
57
+ cleanup
58
+ rescue DeadActorError
59
+ end
60
+
61
+ def cleanup
62
+ @registry.delete(@name) if @name
63
+ end
64
+
65
+ private
66
+
67
+ def add_accessors
68
+ remove_accessors
69
+ if @configuration[:accessors].is_a? Array
70
+ # TODO: Decide which level to keep, and only keep that.
71
+ # Do we provide access by Celluloid.accessor
72
+ # Do we provide access by Celluloid.actor_system.accessor
73
+ @configuration[:accessors].each do |name|
74
+ Celluloid.instance_exec(@configuration[:as], name) do |actor, _where|
75
+ define_method(name) do
76
+ Celluloid.actor_system[actor]
77
+ end
78
+ end
79
+ Celluloid::Actor::System.instance_exec(@configuration[:as], name) do |actor, _where|
80
+ define_method(name) do
81
+ Celluloid.actor_system[actor]
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ def remove_accessors
89
+ if @configuration[:accessors].is_a? Array
90
+ @configuration[:accessors].each do |name|
91
+ Celluloid.instance_eval do
92
+ remove_method(name) rescue nil # avoid warnings in tests
93
+ end
94
+ Celluloid::Actor::System.instance_eval do
95
+ remove_method(name) rescue nil # avoid warnings in tests
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def invoke_injection(name)
102
+ return unless @injections
103
+ block = @injections[name]
104
+ instance_eval(&block) if block.is_a? Proc
105
+ end
106
+
107
+ # Executes args if it has the method #call, and converts the return
108
+ # value to an Array. Otherwise, it just converts it to an Array.
109
+ def prepare_args(args)
110
+ args = args.call if args.respond_to?(:call)
111
+ Array(args)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,210 @@
1
+ module Celluloid
2
+ module Supervision
3
+ class Container
4
+ # Manages a fixed-size pool of actors
5
+ # Delegates work (i.e. methods) and supervises actors
6
+ # Don't use this class directly. Instead use MyKlass.pool
7
+ class Pool
8
+ include Celluloid
9
+
10
+ trap_exit :__crash_handler__
11
+ finalizer :__shutdown__
12
+
13
+ attr_reader :size, :actors
14
+
15
+ def initialize(options = {})
16
+ @idle = []
17
+ @busy = []
18
+ @klass = options[:actors]
19
+ @actors = Set.new
20
+ @mutex = Mutex.new
21
+
22
+ @size = options[:size] || [Celluloid.cores || 2, 2].max
23
+ @args = options[:args] ? Array(options[:args]) : []
24
+
25
+ # Do this last since it can suspend and/or crash
26
+ @idle = @size.times.map { __spawn_actor__ }
27
+ end
28
+
29
+ def __shutdown__
30
+ return unless defined?(@actors) && @actors
31
+ # TODO: these can be nil if initializer crashes
32
+ terminators = @actors.map do |actor|
33
+ begin
34
+ actor.future(:terminate)
35
+ rescue DeadActorError
36
+ end
37
+ end
38
+
39
+ terminators.compact.each { |terminator| terminator.value rescue nil }
40
+ end
41
+
42
+ def _send_(method, *args, &block)
43
+ actor = __provision_actor__
44
+ begin
45
+ actor._send_ method, *args, &block
46
+ rescue DeadActorError # if we get a dead actor out of the pool
47
+ wait :respawn_complete
48
+ actor = __provision_actor__
49
+ retry
50
+ rescue ::Exception => ex
51
+ abort ex
52
+ ensure
53
+ if actor.alive?
54
+ @idle << actor
55
+ @busy.delete actor
56
+
57
+ # Broadcast that actor is done processing and
58
+ # waiting idle
59
+ signal :actor_idle
60
+ end
61
+ end
62
+ end
63
+
64
+ def name
65
+ _send_ @mailbox, :name
66
+ end
67
+
68
+ def is_a?(klass)
69
+ _send_ :is_a?, klass
70
+ end
71
+
72
+ def kind_of?(klass)
73
+ _send_ :kind_of?, klass
74
+ end
75
+
76
+ def methods(include_ancestors = true)
77
+ _send_ :methods, include_ancestors
78
+ end
79
+
80
+ def to_s
81
+ _send_ :to_s
82
+ end
83
+
84
+ def inspect
85
+ _send_ :inspect
86
+ end
87
+
88
+ def size=(new_size)
89
+ new_size = [0, new_size].max
90
+ if new_size > size
91
+ delta = new_size - size
92
+ delta.times { @idle << __spawn_actor__ }
93
+ else
94
+ (size - new_size).times do
95
+ actor = __provision_actor__
96
+ unlink actor
97
+ @busy.delete actor
98
+ @actors.delete actor
99
+ actor.terminate
100
+ end
101
+ end
102
+ @size = new_size
103
+ end
104
+
105
+ def busy_size
106
+ @mutex.synchronize { @busy.length }
107
+ end
108
+
109
+ def idle_size
110
+ @mutex.synchronize { @idle.length }
111
+ end
112
+
113
+ def __idle?(actor)
114
+ @mutex.synchronize { @idle.include? actor }
115
+ end
116
+
117
+ def __busy?(actor)
118
+ @mutex.synchronize { @busy.include? actor }
119
+ end
120
+
121
+ def __busy
122
+ @mutex.synchronize { @busy }
123
+ end
124
+
125
+ def __idle
126
+ @mutex.synchronize { @idle }
127
+ end
128
+
129
+ def __state(actor)
130
+ return :busy if __busy?(actor)
131
+ return :idle if __idle?(actor)
132
+ :missing
133
+ end
134
+
135
+ # Instantiate an actor, add it to the actor Set, and return it
136
+ def __spawn_actor__
137
+ actor = @klass.new_link(*@args)
138
+ @mutex.synchronize { @actors.add(actor) }
139
+ @actors.add(actor)
140
+ actor
141
+ end
142
+
143
+ # Provision a new actor ( take it out of idle, move it into busy, and avail it )
144
+ def __provision_actor__
145
+ Task.current.guard_warnings = true
146
+ @mutex.synchronize do
147
+ while @idle.empty?
148
+ # Wait for responses from one of the busy actors
149
+ response = exclusive { receive { |msg| msg.is_a?(Internals::Response) } }
150
+ Thread.current[:celluloid_actor].handle_message(response)
151
+ end
152
+
153
+ actor = @idle.shift
154
+ @busy << actor
155
+ actor
156
+ end
157
+ end
158
+
159
+ # Spawn a new worker for every crashed one
160
+ def __crash_handler__(actor, reason)
161
+ @busy.delete actor
162
+ @idle.delete actor
163
+ @actors.delete actor
164
+ return unless reason
165
+ @idle << __spawn_actor__
166
+ signal :respawn_complete
167
+ end
168
+
169
+ def respond_to?(meth, include_private = false)
170
+ # NOTE: use method() here since this class
171
+ # shouldn't be used directly, and method() is less
172
+ # likely to be "reimplemented" inconsistently
173
+ # with other Object.*method* methods.
174
+
175
+ found = method(meth)
176
+ if include_private
177
+ found ? true : false
178
+ else
179
+ if found.is_a?(UnboundMethod)
180
+ found.owner.public_instance_methods.include?(meth) ||
181
+ found.owner.protected_instance_methods.include?(meth)
182
+ else
183
+ found.receiver.public_methods.include?(meth) ||
184
+ found.receiver.protected_methods.include?(meth)
185
+ end
186
+ end
187
+ rescue NameError
188
+ false
189
+ end
190
+
191
+ def method_missing(method, *args, &block)
192
+ if respond_to?(method)
193
+ _send_ method, *args, &block
194
+ else
195
+ super
196
+ end
197
+ end
198
+
199
+ # Since Pool allocates worker objects only just before calling them,
200
+ # we can still help Celluloid::Call detect passing invalid parameters to
201
+ # async methods by checking for those methods on the worker class
202
+ def method(meth)
203
+ super
204
+ rescue NameError
205
+ @klass.instance_method(meth.to_sym)
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,9 @@
1
+ # TODO: Remove at 0.19.0
2
+ module Celluloid
3
+ SupervisionGroup = Supervision::Container
4
+ Supervision::Group = Supervision::Container
5
+ Supervision::Member = Supervision::Container::Instance
6
+ end
7
+
8
+ require "celluloid/supervision/deprecate/supervise"
9
+ require "celluloid/supervision/deprecate/validation"
@@ -0,0 +1,105 @@
1
+ # TODO: Remove at 0.19.0
2
+ module Celluloid
3
+ class << self
4
+ undef supervise rescue nil
5
+ def supervise(*args, &block)
6
+ supervisor = Supervision.router(*args)
7
+ supervisor.supervise(*args, &block)
8
+ end
9
+ undef supervise_as rescue nil
10
+ def supervise_as(name, *args, &block)
11
+ supervisor = Supervision.router(*args)
12
+ supervisor.supervise_as(name, *args, &block)
13
+ end
14
+ end
15
+ module ClassMethods
16
+ undef supervise rescue nil
17
+ def supervise(*args, &block)
18
+ args.unshift(self)
19
+ Celluloid.supervise(*args, &block)
20
+ end
21
+ undef supervise_as rescue nil
22
+ def supervise_as(name, *args, &block)
23
+ args.unshift(self)
24
+ Celluloid.supervise_as(name, *args, &block)
25
+ end
26
+ end
27
+
28
+ # Supervisors are actors that watch over other actors and restart them if
29
+ # they crash
30
+ class Supervisor
31
+ class << self
32
+ # Define the root of the supervision tree
33
+ attr_accessor :root
34
+
35
+ undef supervise rescue nil
36
+ def supervise(klass, *args, &block)
37
+ args.unshift(klass)
38
+ Celluloid.supervise(*args, &block)
39
+ end
40
+
41
+ undef supervise_as rescue nil
42
+ def supervise_as(name, klass, *args, &block)
43
+ args.unshift(klass)
44
+ Celluloid.supervise_as(name, *args, &block)
45
+ end
46
+ end
47
+ end
48
+
49
+ module Supervision
50
+ class << self
51
+ undef router rescue nil
52
+ def router(*_args)
53
+ # TODO: Actually route, based on :branch, if present; or else:
54
+ Celluloid.services
55
+ end
56
+ end
57
+ class Container
58
+ class << self
59
+ undef run! rescue nil
60
+ def run!(*args)
61
+ container = new(*args) do |g|
62
+ blocks.each do |block|
63
+ block.call(g)
64
+ end
65
+ end
66
+ container
67
+ end
68
+
69
+ undef run rescue nil
70
+ def run(*args)
71
+ loop do
72
+ supervisor = run!(*args)
73
+ # Take five, toplevel supervisor
74
+ sleep 5 while supervisor.alive? # Why 5?
75
+ Internals::Logger.error "!!! Celluloid::Supervision::Container #{self} crashed. Restarting..."
76
+ end
77
+ end
78
+
79
+ undef supervise rescue nil
80
+ def supervise(*args, &block)
81
+ blocks << lambda do |container|
82
+ container.supervise(*args, &block)
83
+ end
84
+ end
85
+
86
+ undef supervise_as rescue nil
87
+ def supervise_as(name, *args, &block)
88
+ blocks << lambda do |container|
89
+ container.supervise_as(name, *args, &block)
90
+ end
91
+ end
92
+ end
93
+
94
+ undef supervise rescue nil
95
+ def supervise(*args, &block)
96
+ add(Configuration.options(args, block: block))
97
+ end
98
+
99
+ undef supervise_as rescue nil
100
+ def supervise_as(name, *args, &block)
101
+ add(Configuration.options(args, block: block, as: name))
102
+ end
103
+ end
104
+ end
105
+ end