celluloid 0.18.0.pre → 0.18.0

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 (177) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +258 -39
  3. data/CONDUCT.md +13 -0
  4. data/CONTRIBUTING.md +39 -0
  5. data/README.md +54 -165
  6. data/REFACTOR.md +1 -0
  7. data/architecture.md +120 -0
  8. data/examples/basic_usage.rb +1 -1
  9. data/examples/configurations.rb +78 -0
  10. data/examples/futures.rb +1 -1
  11. data/examples/ring.rb +5 -4
  12. data/examples/simple_pmap.rb +1 -1
  13. data/examples/stack.rb +2 -2
  14. data/examples/supervisors_and_registry.rb +82 -0
  15. data/examples/timers.rb +2 -2
  16. data/lib/celluloid.rb +72 -47
  17. data/lib/celluloid/actor.rb +27 -17
  18. data/lib/celluloid/actor/system.rb +13 -29
  19. data/lib/celluloid/autostart.rb +5 -5
  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/debug.rb +3 -0
  27. data/lib/celluloid/exceptions.rb +2 -2
  28. data/lib/celluloid/future.rb +7 -9
  29. data/lib/celluloid/group.rb +12 -8
  30. data/lib/celluloid/group/pool.rb +1 -3
  31. data/lib/celluloid/group/spawner.rb +2 -6
  32. data/lib/celluloid/internals/call_chain.rb +15 -0
  33. data/lib/celluloid/internals/cpu_counter.rb +62 -0
  34. data/lib/celluloid/internals/handlers.rb +42 -0
  35. data/lib/celluloid/internals/links.rb +38 -0
  36. data/lib/celluloid/internals/logger.rb +104 -0
  37. data/lib/celluloid/internals/method.rb +34 -0
  38. data/lib/celluloid/internals/properties.rb +32 -0
  39. data/lib/celluloid/internals/receivers.rb +64 -0
  40. data/lib/celluloid/internals/registry.rb +102 -0
  41. data/lib/celluloid/internals/responses.rb +46 -0
  42. data/lib/celluloid/internals/signals.rb +24 -0
  43. data/lib/celluloid/internals/stack.rb +74 -0
  44. data/lib/celluloid/internals/stack/dump.rb +12 -0
  45. data/lib/celluloid/internals/stack/states.rb +72 -0
  46. data/lib/celluloid/internals/stack/summary.rb +12 -0
  47. data/lib/celluloid/internals/task_set.rb +51 -0
  48. data/lib/celluloid/internals/thread_handle.rb +52 -0
  49. data/lib/celluloid/internals/uuid.rb +40 -0
  50. data/lib/celluloid/logging/incident.rb +21 -0
  51. data/lib/celluloid/logging/incident_logger.rb +147 -0
  52. data/lib/celluloid/logging/incident_reporter.rb +49 -0
  53. data/lib/celluloid/logging/log_event.rb +20 -0
  54. data/lib/celluloid/logging/ring_buffer.rb +64 -0
  55. data/lib/celluloid/mailbox.rb +22 -9
  56. data/lib/celluloid/mailbox/evented.rb +13 -5
  57. data/lib/celluloid/notifications.rb +95 -0
  58. data/lib/celluloid/pool.rb +6 -0
  59. data/lib/celluloid/probe.rb +81 -0
  60. data/lib/celluloid/proxy/abstract.rb +9 -9
  61. data/lib/celluloid/proxy/async.rb +1 -1
  62. data/lib/celluloid/proxy/block.rb +2 -2
  63. data/lib/celluloid/proxy/cell.rb +1 -1
  64. data/lib/celluloid/proxy/future.rb +2 -4
  65. data/lib/celluloid/proxy/sync.rb +1 -3
  66. data/lib/celluloid/rspec.rb +22 -33
  67. data/lib/celluloid/supervision.rb +17 -0
  68. data/lib/celluloid/supervision/configuration.rb +169 -0
  69. data/lib/celluloid/supervision/configuration/injections.rb +8 -0
  70. data/lib/celluloid/supervision/configuration/instance.rb +113 -0
  71. data/lib/celluloid/supervision/constants.rb +123 -0
  72. data/lib/celluloid/supervision/container.rb +144 -0
  73. data/lib/celluloid/supervision/container/behavior.rb +89 -0
  74. data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
  75. data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
  76. data/lib/celluloid/supervision/container/injections.rb +8 -0
  77. data/lib/celluloid/supervision/container/instance.rb +116 -0
  78. data/lib/celluloid/supervision/container/pool.rb +210 -0
  79. data/lib/celluloid/supervision/service.rb +27 -0
  80. data/lib/celluloid/supervision/supervise.rb +34 -0
  81. data/lib/celluloid/supervision/validation.rb +40 -0
  82. data/lib/celluloid/supervision/version.rb +5 -0
  83. data/lib/celluloid/system_events.rb +11 -6
  84. data/lib/celluloid/task.rb +25 -12
  85. data/lib/celluloid/task/fibered.rb +2 -0
  86. data/lib/celluloid/task/threaded.rb +3 -3
  87. data/lib/celluloid/test.rb +5 -2
  88. data/lib/celluloid/thread.rb +0 -2
  89. data/lib/celluloid/version.rb +1 -1
  90. data/spec/celluloid/block_spec.rb +29 -32
  91. data/spec/celluloid/calls_spec.rb +5 -15
  92. data/spec/celluloid/future_spec.rb +2 -2
  93. data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
  94. data/spec/celluloid/internals/links_spec.rb +43 -0
  95. data/spec/celluloid/internals/properties_spec.rb +40 -0
  96. data/spec/celluloid/internals/registry_spec.rb +62 -0
  97. data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
  98. data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
  99. data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
  100. data/spec/celluloid/internals/uuid_spec.rb +9 -0
  101. data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
  102. data/spec/celluloid/mailbox/evented_spec.rb +11 -22
  103. data/spec/celluloid/misc/leak_spec.rb +3 -4
  104. data/spec/celluloid/notifications_spec.rb +140 -0
  105. data/spec/celluloid/probe_spec.rb +102 -0
  106. data/spec/celluloid/proxy_spec.rb +30 -30
  107. data/spec/celluloid/supervision/behavior_spec.rb +74 -0
  108. data/spec/celluloid/supervision/configuration_spec.rb +181 -0
  109. data/spec/celluloid/supervision/container_spec.rb +72 -0
  110. data/spec/celluloid/supervision/instance_spec.rb +13 -0
  111. data/spec/celluloid/supervision/root_spec.rb +28 -0
  112. data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
  113. data/spec/celluloid/task/fibered_spec.rb +1 -3
  114. data/spec/celluloid/task/threaded_spec.rb +1 -3
  115. data/spec/shared/actor_examples.rb +58 -33
  116. data/spec/shared/group_examples.rb +2 -2
  117. data/spec/shared/mailbox_examples.rb +1 -1
  118. data/spec/shared/stack_examples.rb +87 -0
  119. data/spec/shared/task_examples.rb +2 -3
  120. data/spec/spec_helper.rb +2 -4
  121. data/spec/support/configure_rspec.rb +2 -3
  122. data/spec/support/coverage.rb +2 -4
  123. data/spec/support/crash_checking.rb +2 -2
  124. data/spec/support/examples/actor_class.rb +3 -8
  125. data/spec/support/examples/call_class.rb +2 -2
  126. data/spec/support/examples/container_class.rb +35 -0
  127. data/spec/support/examples/evented_mailbox_class.rb +1 -2
  128. data/spec/support/examples/stack_classes.rb +58 -0
  129. data/spec/support/examples/stack_methods.rb +23 -0
  130. data/spec/support/examples/subordinate_class.rb +19 -0
  131. data/spec/support/logging.rb +2 -34
  132. data/spec/support/loose_threads.rb +3 -16
  133. data/spec/support/reset_class_variables.rb +5 -1
  134. data/spec/support/stubbing.rb +1 -1
  135. metadata +91 -323
  136. data/culture/CONDUCT.md +0 -38
  137. data/culture/GSoC/1010-why_we_will_participate.md +0 -17
  138. data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
  139. data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
  140. data/culture/GSoC/1040-getting_students_involved.md +0 -5
  141. data/culture/GSoC/1050-student_involvement_after.md +0 -5
  142. data/culture/GSoC/README.md +0 -16
  143. data/culture/Gemfile +0 -9
  144. data/culture/LICENSE.txt +0 -22
  145. data/culture/README.md +0 -22
  146. data/culture/Rakefile +0 -5
  147. data/culture/SYNC.md +0 -70
  148. data/culture/celluloid-culture.gemspec +0 -18
  149. data/culture/gems/README.md +0 -39
  150. data/culture/gems/dependencies.yml +0 -93
  151. data/culture/gems/loader.rb +0 -101
  152. data/culture/rubocop/README.md +0 -38
  153. data/culture/rubocop/lint.yml +0 -8
  154. data/culture/rubocop/metrics.yml +0 -15
  155. data/culture/rubocop/perf.yml +0 -0
  156. data/culture/rubocop/rubocop.yml +0 -5
  157. data/culture/rubocop/style.yml +0 -61
  158. data/culture/spec/gems_spec.rb +0 -2
  159. data/culture/spec/spec_helper.rb +0 -0
  160. data/culture/spec/sync_spec.rb +0 -2
  161. data/culture/sync.rb +0 -56
  162. data/culture/tasks/rspec.rake +0 -5
  163. data/culture/tasks/rubocop.rake +0 -2
  164. data/lib/celluloid/actor/manager.rb +0 -7
  165. data/lib/celluloid/backported.rb +0 -2
  166. data/lib/celluloid/current.rb +0 -2
  167. data/lib/celluloid/deprecate.rb +0 -34
  168. data/lib/celluloid/fiber.rb +0 -32
  169. data/lib/celluloid/managed.rb +0 -3
  170. data/lib/celluloid/notices.rb +0 -15
  171. data/spec/deprecate/actor_system_spec.rb +0 -72
  172. data/spec/deprecate/block_spec.rb +0 -52
  173. data/spec/deprecate/calls_spec.rb +0 -39
  174. data/spec/deprecate/evented_mailbox_spec.rb +0 -34
  175. data/spec/deprecate/future_spec.rb +0 -32
  176. data/spec/deprecate/internal_pool_spec.rb +0 -4
  177. data/spec/support/env.rb +0 -21
@@ -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,27 @@
1
+ module Celluloid
2
+ module Supervision
3
+ module Service
4
+ class Root < Container
5
+ class << self
6
+ def define
7
+ super({
8
+ supervise: Celluloid.actor_system.root_configuration,
9
+ as: :root_supervisor,
10
+ accessors: [:root],
11
+ branch: :root,
12
+ type: self
13
+ })
14
+ end
15
+
16
+ def deploy(instances)
17
+ super(supervise: instances, branch: :root, as: :root, type: self)
18
+ end
19
+ end
20
+ def provider
21
+ Celluloid.root_services
22
+ end
23
+ end
24
+ class Public < Container; end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ # collect together all instances of the `supervise` method
2
+ module Celluloid
3
+ class << self
4
+ def supervise(config = {}, &block)
5
+ supervisor = Supervision.router(config)
6
+ supervisor.supervise(config, &block)
7
+ end
8
+ end
9
+ module ClassMethods
10
+ def supervise(config = {}, &block)
11
+ Celluloid.supervise(config.merge(type: self), &block)
12
+ end
13
+ end
14
+ module Supervision
15
+ class << self
16
+ def router(_config = {})
17
+ # TODO: Actually route.
18
+ Celluloid.services # for now, hardcode .services
19
+ end
20
+ end
21
+ class Container
22
+ class << self
23
+ def supervise(config, &block)
24
+ blocks << lambda do |container|
25
+ container.add(config, &block)
26
+ end
27
+ end
28
+ end
29
+ def supervise(config, &block)
30
+ add(Configuration.options(config, block: block))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ module Celluloid
2
+ module Supervision
3
+ class Configuration
4
+ class << self
5
+ def valid?(configuration, fails = false)
6
+ parameters(:mandatory).each do |k|
7
+ unless configuration.key? k
8
+ if fails
9
+ raise Error::Incomplete, "Missing `:#{k}` in supervision configuration."
10
+ else
11
+ return false
12
+ end
13
+ end
14
+ end
15
+ arity.each do |klass, args|
16
+ next if configuration[args].is_a? Proc
17
+ __a = configuration[args] && configuration[args].count || 0
18
+ __arity = configuration[klass].allocate.method(:initialize).arity
19
+ unless (__arity < 0 && __a >= __arity.abs - 1) || __a == __arity.abs
20
+ if fails
21
+ raise ArgumentError, "#{__a} vs. #{__arity}"
22
+ else
23
+ return false
24
+ end
25
+ end
26
+ end
27
+ true
28
+ end
29
+
30
+ def options(config = {}, options = {})
31
+ configuration = config.merge(options)
32
+ return configuration if configuration.is_a? Configuration
33
+ configuration[:configuration] = Container::Behavior.configure(configuration)
34
+ valid?(configuration, true)
35
+ configuration
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ module Celluloid
2
+ module Supervision
3
+ VERSION = "0.20.6".freeze
4
+ end
5
+ end