celluloid 0.17.2 → 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.
- checksums.yaml +5 -5
- data/CHANGES.md +340 -75
- data/CONDUCT.md +13 -0
- data/CONTRIBUTING.md +39 -0
- data/LICENSE.txt +1 -1
- data/README.md +54 -150
- data/REFACTOR.md +1 -0
- data/architecture.md +120 -0
- data/examples/basic_usage.rb +1 -1
- data/examples/configurations.rb +78 -0
- data/examples/futures.rb +1 -1
- data/examples/ring.rb +5 -4
- data/examples/simple_pmap.rb +1 -1
- data/examples/stack.rb +2 -2
- data/examples/supervisors_and_registry.rb +82 -0
- data/examples/timers.rb +2 -2
- data/lib/celluloid.rb +78 -65
- data/lib/celluloid/actor.rb +27 -17
- data/lib/celluloid/actor/system.rb +13 -29
- data/lib/celluloid/autostart.rb +6 -1
- data/lib/celluloid/call/async.rb +2 -0
- data/lib/celluloid/call/sync.rb +10 -3
- data/lib/celluloid/calls.rb +13 -13
- data/lib/celluloid/cell.rb +5 -9
- data/lib/celluloid/condition.rb +3 -3
- data/lib/celluloid/core_ext.rb +0 -2
- data/lib/celluloid/debug.rb +3 -0
- data/lib/celluloid/exceptions.rb +2 -2
- data/lib/celluloid/future.rb +8 -10
- data/lib/celluloid/group.rb +16 -6
- data/lib/celluloid/group/pool.rb +1 -3
- data/lib/celluloid/group/spawner.rb +2 -6
- data/lib/celluloid/internals/call_chain.rb +15 -0
- data/lib/celluloid/internals/cpu_counter.rb +62 -0
- data/lib/celluloid/internals/handlers.rb +42 -0
- data/lib/celluloid/internals/links.rb +38 -0
- data/lib/celluloid/internals/logger.rb +104 -0
- data/lib/celluloid/internals/method.rb +34 -0
- data/lib/celluloid/internals/properties.rb +32 -0
- data/lib/celluloid/internals/receivers.rb +64 -0
- data/lib/celluloid/internals/registry.rb +102 -0
- data/lib/celluloid/internals/responses.rb +46 -0
- data/lib/celluloid/internals/signals.rb +24 -0
- data/lib/celluloid/internals/stack.rb +74 -0
- data/lib/celluloid/internals/stack/dump.rb +12 -0
- data/lib/celluloid/internals/stack/states.rb +72 -0
- data/lib/celluloid/internals/stack/summary.rb +12 -0
- data/lib/celluloid/internals/task_set.rb +51 -0
- data/lib/celluloid/internals/thread_handle.rb +52 -0
- data/lib/celluloid/internals/uuid.rb +40 -0
- data/lib/celluloid/logging/incident.rb +21 -0
- data/lib/celluloid/logging/incident_logger.rb +147 -0
- data/lib/celluloid/logging/incident_reporter.rb +49 -0
- data/lib/celluloid/logging/log_event.rb +20 -0
- data/lib/celluloid/logging/ring_buffer.rb +64 -0
- data/lib/celluloid/mailbox.rb +22 -9
- data/lib/celluloid/mailbox/evented.rb +13 -7
- data/lib/celluloid/notifications.rb +95 -0
- data/lib/celluloid/pool.rb +6 -0
- data/lib/celluloid/probe.rb +81 -0
- data/lib/celluloid/proxy/abstract.rb +38 -7
- data/lib/celluloid/proxy/actor.rb +0 -5
- data/lib/celluloid/proxy/async.rb +2 -18
- data/lib/celluloid/proxy/block.rb +2 -1
- data/lib/celluloid/proxy/cell.rb +1 -7
- data/lib/celluloid/proxy/future.rb +3 -21
- data/lib/celluloid/proxy/sync.rb +2 -20
- data/lib/celluloid/rspec.rb +22 -34
- data/lib/celluloid/supervision.rb +17 -0
- data/lib/celluloid/supervision/configuration.rb +169 -0
- data/lib/celluloid/supervision/configuration/injections.rb +8 -0
- data/lib/celluloid/supervision/configuration/instance.rb +113 -0
- data/lib/celluloid/supervision/constants.rb +123 -0
- data/lib/celluloid/supervision/container.rb +144 -0
- data/lib/celluloid/supervision/container/behavior.rb +89 -0
- data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
- data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
- data/lib/celluloid/supervision/container/injections.rb +8 -0
- data/lib/celluloid/supervision/container/instance.rb +116 -0
- data/lib/celluloid/supervision/container/pool.rb +210 -0
- data/lib/celluloid/supervision/service.rb +27 -0
- data/lib/celluloid/supervision/supervise.rb +34 -0
- data/lib/celluloid/supervision/validation.rb +40 -0
- data/lib/celluloid/supervision/version.rb +5 -0
- data/lib/celluloid/system_events.rb +10 -3
- data/lib/celluloid/task.rb +25 -12
- data/lib/celluloid/task/fibered.rb +6 -2
- data/lib/celluloid/task/threaded.rb +3 -3
- data/lib/celluloid/test.rb +5 -2
- data/lib/celluloid/thread.rb +0 -2
- data/lib/celluloid/version.rb +1 -1
- data/spec/celluloid/block_spec.rb +29 -32
- data/spec/celluloid/calls_spec.rb +5 -15
- data/spec/celluloid/future_spec.rb +7 -1
- data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
- data/spec/celluloid/internals/links_spec.rb +43 -0
- data/spec/celluloid/internals/properties_spec.rb +40 -0
- data/spec/celluloid/internals/registry_spec.rb +62 -0
- data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
- data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
- data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
- data/spec/celluloid/internals/uuid_spec.rb +9 -0
- data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
- data/spec/celluloid/mailbox/evented_spec.rb +21 -19
- data/spec/celluloid/misc/leak_spec.rb +3 -4
- data/spec/celluloid/notifications_spec.rb +140 -0
- data/spec/celluloid/probe_spec.rb +102 -0
- data/spec/celluloid/proxy_spec.rb +33 -0
- data/spec/celluloid/supervision/behavior_spec.rb +74 -0
- data/spec/celluloid/supervision/configuration_spec.rb +181 -0
- data/spec/celluloid/supervision/container_spec.rb +72 -0
- data/spec/celluloid/supervision/instance_spec.rb +13 -0
- data/spec/celluloid/supervision/root_spec.rb +28 -0
- data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
- data/spec/celluloid/task/fibered_spec.rb +1 -3
- data/spec/celluloid/task/threaded_spec.rb +1 -3
- data/spec/shared/actor_examples.rb +65 -29
- data/spec/shared/group_examples.rb +2 -2
- data/spec/shared/mailbox_examples.rb +1 -1
- data/spec/shared/stack_examples.rb +87 -0
- data/spec/shared/task_examples.rb +2 -3
- data/spec/spec_helper.rb +2 -4
- data/spec/support/configure_rspec.rb +3 -4
- data/spec/support/coverage.rb +2 -4
- data/spec/support/crash_checking.rb +2 -2
- data/spec/support/examples/actor_class.rb +3 -8
- data/spec/support/examples/call_class.rb +2 -2
- data/spec/support/examples/container_class.rb +35 -0
- data/spec/support/examples/evented_mailbox_class.rb +1 -2
- data/spec/support/examples/stack_classes.rb +58 -0
- data/spec/support/examples/stack_methods.rb +23 -0
- data/spec/support/examples/subordinate_class.rb +19 -0
- data/spec/support/logging.rb +3 -34
- data/spec/support/loose_threads.rb +3 -24
- data/spec/support/reset_class_variables.rb +5 -1
- data/spec/support/stubbing.rb +1 -1
- metadata +93 -291
- data/culture/CONDUCT.md +0 -28
- data/culture/Gemfile +0 -9
- data/culture/LICENSE.txt +0 -22
- data/culture/README.md +0 -22
- data/culture/Rakefile +0 -5
- data/culture/SYNC.md +0 -70
- data/culture/celluloid-culture.gemspec +0 -18
- data/culture/gems/README.md +0 -39
- data/culture/gems/dependencies.yml +0 -85
- data/culture/gems/loader.rb +0 -101
- data/culture/rubocop/README.md +0 -38
- data/culture/rubocop/lint.yml +0 -8
- data/culture/rubocop/metrics.yml +0 -15
- data/culture/rubocop/perf.yml +0 -0
- data/culture/rubocop/rubocop.yml +0 -5
- data/culture/rubocop/style.yml +0 -57
- data/culture/spec/gems_spec.rb +0 -2
- data/culture/spec/spec_helper.rb +0 -0
- data/culture/spec/sync_spec.rb +0 -2
- data/culture/sync.rb +0 -56
- data/culture/tasks/rspec.rake +0 -5
- data/culture/tasks/rubocop.rake +0 -2
- data/lib/celluloid/actor/manager.rb +0 -7
- data/lib/celluloid/backported.rb +0 -2
- data/lib/celluloid/current.rb +0 -2
- data/lib/celluloid/deprecate.rb +0 -21
- data/lib/celluloid/fiber.rb +0 -32
- data/lib/celluloid/managed.rb +0 -3
- data/lib/celluloid/notices.rb +0 -15
- data/spec/celluloid/actor/manager_spec.rb +0 -0
- data/spec/deprecate/actor_system_spec.rb +0 -72
- data/spec/deprecate/block_spec.rb +0 -52
- data/spec/deprecate/calls_spec.rb +0 -39
- data/spec/deprecate/evented_mailbox_spec.rb +0 -34
- data/spec/deprecate/future_spec.rb +0 -32
- data/spec/deprecate/internal_pool_spec.rb +0 -4
- data/spec/support/env.rb +0 -21
@@ -0,0 +1,17 @@
|
|
1
|
+
require "celluloid" unless defined? Celluloid
|
2
|
+
|
3
|
+
require "celluloid/supervision/constants"
|
4
|
+
require "celluloid/supervision/supervise"
|
5
|
+
|
6
|
+
require "celluloid/supervision/container"
|
7
|
+
require "celluloid/supervision/container/instance"
|
8
|
+
require "celluloid/supervision/container/behavior"
|
9
|
+
require "celluloid/supervision/container/injections"
|
10
|
+
|
11
|
+
require "celluloid/supervision/container/behavior/tree"
|
12
|
+
|
13
|
+
require "celluloid/supervision/validation"
|
14
|
+
require "celluloid/supervision/configuration"
|
15
|
+
require "celluloid/supervision/configuration/instance"
|
16
|
+
|
17
|
+
require "celluloid/supervision/service"
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Celluloid
|
2
|
+
module Supervision
|
3
|
+
class Configuration
|
4
|
+
class << self
|
5
|
+
def deploy(options = {})
|
6
|
+
define(options).deploy
|
7
|
+
end
|
8
|
+
|
9
|
+
def define(options = {})
|
10
|
+
new(options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
def_delegators :current_instance,
|
17
|
+
:delete,
|
18
|
+
:key?,
|
19
|
+
:set,
|
20
|
+
:get,
|
21
|
+
:[],
|
22
|
+
:[]=,
|
23
|
+
:injection!,
|
24
|
+
:injections!
|
25
|
+
|
26
|
+
attr_accessor :instances
|
27
|
+
|
28
|
+
def initialize(options = {})
|
29
|
+
@instances = [Instance.new]
|
30
|
+
@branch = :services
|
31
|
+
@i = 0 # incrementer of instances in this branch
|
32
|
+
resync_accessors
|
33
|
+
@configuration = options
|
34
|
+
|
35
|
+
if options.is_a? Hash
|
36
|
+
options[:configuration] ||= Container::Behavior.configure(options)
|
37
|
+
@configuration = instance_eval(&options[:configuration])
|
38
|
+
@supervisor ||= @configuration.fetch(:supervisor, :"Celluloid.services")
|
39
|
+
end
|
40
|
+
@supervisor ||= :"Celluloid.services"
|
41
|
+
|
42
|
+
define(@configuration) if (@configuration.is_a?(Hash) || @configuration.is_a?(Array)) && @configuration.any?
|
43
|
+
end
|
44
|
+
|
45
|
+
def provider
|
46
|
+
@provider ||= if @supervisor.is_a? Hash
|
47
|
+
@supervisor[:type].run!(@supervisor)
|
48
|
+
elsif @supervisor.is_a? Symbol
|
49
|
+
@supervisor = Object.module_eval(@supervisor.to_s)
|
50
|
+
provider
|
51
|
+
elsif @supervisor.is_a? Class
|
52
|
+
@supervisor.run!
|
53
|
+
elsif @supervisor.respond_to? :supervise
|
54
|
+
@supervisor
|
55
|
+
else
|
56
|
+
raise Error::InvalidSupervisor
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def deploy(options = {})
|
61
|
+
define(options) if options.any?
|
62
|
+
@instances.each do |instance|
|
63
|
+
provider.add instance.merge(branch: @branch)
|
64
|
+
end
|
65
|
+
provider
|
66
|
+
end
|
67
|
+
|
68
|
+
def count
|
69
|
+
@instances.count
|
70
|
+
end
|
71
|
+
|
72
|
+
def each(&block)
|
73
|
+
@instances.each(&block)
|
74
|
+
end
|
75
|
+
|
76
|
+
def resync_accessors
|
77
|
+
# methods for setting and getting the usual defaults
|
78
|
+
Configuration.parameters(:mandatory, :optional, :plugins, :meta).each do |key|
|
79
|
+
[:"#{key}!", :"#{key}="].each do |m|
|
80
|
+
self.class.instance_eval do
|
81
|
+
remove_method :"#{m}" rescue nil # avoid warnings in tests
|
82
|
+
define_method(m) { |p| current_instance.send(m, p) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
[:"#{key}?", :"#{key}"].each do |m|
|
86
|
+
self.class.instance_eval do
|
87
|
+
remove_method :"#{m}" rescue nil # avoid warnings in tests
|
88
|
+
define_method(m) { current_instance.send(m) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
Configuration.aliases.each do |_alias, _original|
|
94
|
+
["!", :"=", :"?", :""]. each do |m|
|
95
|
+
self.class.instance_eval do
|
96
|
+
remove_method :"#{_alias}#{m}" rescue nil # avoid warnings in tests
|
97
|
+
alias_method :"#{_alias}#{m}", :"#{_original}#{m}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def merge!(values)
|
104
|
+
if values.is_a?(Configuration) || values.is_a?(Hash)
|
105
|
+
current_instance.merge!(values)
|
106
|
+
else
|
107
|
+
raise Error::Invalid
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def merge(values)
|
112
|
+
if values.is_a?(Configuration) || values.is_a?(Hash)
|
113
|
+
current_instance.merge(values)
|
114
|
+
else
|
115
|
+
raise Error::Invalid
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def export
|
120
|
+
return current_instance.to_hash if @i == 0
|
121
|
+
@instances.map(&:export)
|
122
|
+
end
|
123
|
+
|
124
|
+
def include?(name)
|
125
|
+
@instances.map(&:name).include? name
|
126
|
+
end
|
127
|
+
|
128
|
+
def define(configuration, fail = false)
|
129
|
+
if configuration.is_a? Array
|
130
|
+
configuration.each { |c| define(c, fail) }
|
131
|
+
else
|
132
|
+
unless include? configuration[:as]
|
133
|
+
begin
|
134
|
+
current_instance.define(configuration, fail)
|
135
|
+
rescue Error::AlreadyDefined
|
136
|
+
increment
|
137
|
+
retry
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
def increment
|
145
|
+
@i += 1
|
146
|
+
end
|
147
|
+
alias another increment
|
148
|
+
|
149
|
+
def add(options)
|
150
|
+
define(options)
|
151
|
+
provider.supervise options if Configuration.valid? options
|
152
|
+
end
|
153
|
+
|
154
|
+
def shutdown
|
155
|
+
@provider.shutdown
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def current_instance
|
161
|
+
@instances[@i] ||= Instance.new
|
162
|
+
end
|
163
|
+
|
164
|
+
def invoke_injection(_point)
|
165
|
+
# de puts "injection? #{point}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Celluloid
|
2
|
+
module Supervision
|
3
|
+
class Configuration
|
4
|
+
class Instance
|
5
|
+
attr_accessor :configuration
|
6
|
+
|
7
|
+
def initialize(configuration = {})
|
8
|
+
@state = :initializing # :ready
|
9
|
+
resync_accessors
|
10
|
+
@configuration = configuration
|
11
|
+
define(configuration) if configuration.any?
|
12
|
+
end
|
13
|
+
|
14
|
+
def export
|
15
|
+
@configuration.reject { |k, _v| REMOVE_AT_EXPORT.include? k }
|
16
|
+
end
|
17
|
+
|
18
|
+
def ready?(fail = false)
|
19
|
+
unless @state == :ready
|
20
|
+
@state = :ready if Configuration.valid? @configuration, fail
|
21
|
+
end
|
22
|
+
@state == :ready
|
23
|
+
end
|
24
|
+
|
25
|
+
def define(instance, fail = false)
|
26
|
+
raise Configuration::Error::AlreadyDefined if ready? fail
|
27
|
+
invoke_injection(:before_configuration)
|
28
|
+
@configuration = Configuration.options(instance)
|
29
|
+
ready?
|
30
|
+
end
|
31
|
+
|
32
|
+
def injection!(key, proc)
|
33
|
+
@configuration[:injections] ||= {}
|
34
|
+
@configuration[:injections][key] = proc
|
35
|
+
end
|
36
|
+
|
37
|
+
def injections!(_procs)
|
38
|
+
@configuration[:injections] = proces
|
39
|
+
end
|
40
|
+
|
41
|
+
def resync_accessors
|
42
|
+
# methods for setting and getting the usual defaults
|
43
|
+
Configuration.parameters(:mandatory, :optional, :plugins, :meta).each do |key|
|
44
|
+
self.class.instance_eval do
|
45
|
+
remove_method :"#{key}!" rescue nil # avoid warnings in tests
|
46
|
+
define_method(:"#{key}!") { |value| @configuration[key] = value }
|
47
|
+
end
|
48
|
+
self.class.instance_eval do
|
49
|
+
remove_method :"#{key}=" rescue nil # avoid warnings in tests
|
50
|
+
define_method(:"#{key}=") { |value| @configuration[key] = value }
|
51
|
+
end
|
52
|
+
self.class.instance_eval do
|
53
|
+
remove_method :"#{key}?" rescue nil # avoid warnings in tests
|
54
|
+
define_method(:"#{key}?") { !@configuration[key].nil? }
|
55
|
+
end
|
56
|
+
self.class.instance_eval do
|
57
|
+
remove_method :"#{key}" rescue nil # avoid warnings in tests
|
58
|
+
define_method(:"#{key}") { @configuration[key] }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Configuration.aliases.each do |_alias, _original|
|
63
|
+
["!", :"=", :"?", :""]. each do |m|
|
64
|
+
self.class.instance_eval do
|
65
|
+
remove_method :"#{_alias}#{m}" rescue nil # avoid warnings in tests
|
66
|
+
alias_method :"#{_alias}#{m}", :"#{_original}#{m}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
def merge!(values)
|
74
|
+
@configuration = @configuration.merge(values)
|
75
|
+
end
|
76
|
+
|
77
|
+
def merge(values)
|
78
|
+
if values.is_a? Configuration
|
79
|
+
@configuration.merge(values.configuration)
|
80
|
+
elsif values.is_a? Hash
|
81
|
+
@configuration.merge(values)
|
82
|
+
else
|
83
|
+
raise Error::Invalid
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def key?(k)
|
88
|
+
@configuration.key?(k)
|
89
|
+
end
|
90
|
+
|
91
|
+
def set(key, value)
|
92
|
+
@configuration[key] = value
|
93
|
+
end
|
94
|
+
alias []= set
|
95
|
+
|
96
|
+
def get(key)
|
97
|
+
@configuration[key]
|
98
|
+
end
|
99
|
+
alias [] get
|
100
|
+
|
101
|
+
def delete(k)
|
102
|
+
@configuration.delete(k)
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def invoke_injection(_point)
|
108
|
+
# de puts "injection? #{point}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Celluloid
|
2
|
+
module Supervision
|
3
|
+
# TODO: Do not hard-code. Allow configurable values.
|
4
|
+
INSTANCE_RETRY_WAIT = 3
|
5
|
+
INSTANCE_RETRY_LIMIT = 5
|
6
|
+
|
7
|
+
module Error
|
8
|
+
class NoPublicService < Celluloid::Error; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Configuration
|
12
|
+
module Error
|
13
|
+
class AlreadyDefined < Celluloid::Error; end
|
14
|
+
class InvalidSupervisor < Celluloid::Error; end
|
15
|
+
class InvalidValues < Celluloid::Error; end
|
16
|
+
class Incomplete < Celluloid::Error; end
|
17
|
+
class Invalid < Celluloid::Error; end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Using class variable so that parameters can be added by plugins.
|
21
|
+
|
22
|
+
@@parameters = {
|
23
|
+
|
24
|
+
mandatory: [:type],
|
25
|
+
|
26
|
+
optional: %i[
|
27
|
+
as
|
28
|
+
args
|
29
|
+
block
|
30
|
+
],
|
31
|
+
|
32
|
+
# TODO: Move these into Behaviors.
|
33
|
+
plugins: [
|
34
|
+
# de :size, # Supervision::Pool
|
35
|
+
# de :routers, # Supervision::Coordinator
|
36
|
+
# de :supervises # Supervision::Tree
|
37
|
+
],
|
38
|
+
|
39
|
+
meta: %i[
|
40
|
+
registry
|
41
|
+
branch
|
42
|
+
method
|
43
|
+
]
|
44
|
+
}
|
45
|
+
|
46
|
+
@@arity = {
|
47
|
+
type: :args
|
48
|
+
}
|
49
|
+
|
50
|
+
@@aliases = {
|
51
|
+
name: :as,
|
52
|
+
kind: :type,
|
53
|
+
# de :pool => :size, # TODO: Move into Behaviors.
|
54
|
+
# de :supervise => :supervises
|
55
|
+
}
|
56
|
+
|
57
|
+
@@defaults = {}
|
58
|
+
|
59
|
+
class << self
|
60
|
+
def save_defaults
|
61
|
+
@@defaults = {
|
62
|
+
parameters: @@parameters.each_with_object({}) { |(k, v), p| p[k] = v.dup; },
|
63
|
+
aliases: @@aliases.dup,
|
64
|
+
arity: @@arity.dup
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def resync_parameters
|
69
|
+
@@parameters = @@defaults[:parameters].each_with_object({}) { |(k, v), p| p[k] = v.dup; }
|
70
|
+
@@aliases = @@defaults[:aliases].dup
|
71
|
+
@@arity = @@defaults[:arity].dup
|
72
|
+
end
|
73
|
+
|
74
|
+
def parameters(*args)
|
75
|
+
args.inject([]) { |parameters, p| parameters += @@parameters[p]; parameters }
|
76
|
+
end
|
77
|
+
|
78
|
+
def parameter!(key, value)
|
79
|
+
@@parameters[key] << value unless @@parameters[key].include? value
|
80
|
+
end
|
81
|
+
|
82
|
+
def arity
|
83
|
+
@@arity
|
84
|
+
end
|
85
|
+
|
86
|
+
def arity!(key, value)
|
87
|
+
@@arity[key] = value
|
88
|
+
end
|
89
|
+
|
90
|
+
def aliases
|
91
|
+
@@aliases
|
92
|
+
end
|
93
|
+
|
94
|
+
def alias!(aliased, original)
|
95
|
+
@@aliases[aliased] = original
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
save_defaults
|
100
|
+
resync_parameters
|
101
|
+
|
102
|
+
# This was originally added for `#pool` and `PoolManager
|
103
|
+
# `:before_initialize` was added to allow detecting `:size => N`
|
104
|
+
# and turning that into a pool. Other uses could be for `coordinator`
|
105
|
+
# appointing a `router` by detecting `:routers => N`, and many other uses.
|
106
|
+
|
107
|
+
################ These are applied inside Supervision::Member ################
|
108
|
+
|
109
|
+
REMOVE_AT_EXPORT = %i[
|
110
|
+
configuration
|
111
|
+
behavior
|
112
|
+
].freeze
|
113
|
+
|
114
|
+
INJECTIONS = %i[
|
115
|
+
configuration
|
116
|
+
before_initialization
|
117
|
+
after_initialization
|
118
|
+
before_start
|
119
|
+
before_restart
|
120
|
+
].freeze
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Celluloid
|
2
|
+
# Supervise actor instances in a container.
|
3
|
+
module Supervision
|
4
|
+
class Container
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
trap_exit :restart_actor
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def define(options)
|
11
|
+
Configuration.define(top(options))
|
12
|
+
end
|
13
|
+
|
14
|
+
def deploy(options)
|
15
|
+
Configuration.deploy(top(options))
|
16
|
+
end
|
17
|
+
|
18
|
+
def top(options)
|
19
|
+
{
|
20
|
+
as: options.delete(:as),
|
21
|
+
type: (options.delete(:type) || self),
|
22
|
+
branch: (options.delete(:branch) || :services),
|
23
|
+
supervise: options.delete(:supervise) || []
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Actors or sub-applications to be supervised
|
28
|
+
def blocks
|
29
|
+
@blocks ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
# Start this application (and watch it with a supervisor)
|
33
|
+
def run!(options = {})
|
34
|
+
container = new(options) do |g|
|
35
|
+
blocks.each do |block|
|
36
|
+
block.call(g)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
container
|
40
|
+
end
|
41
|
+
|
42
|
+
# Run the application in the foreground with a simple watchdog
|
43
|
+
def run(options = {})
|
44
|
+
loop do
|
45
|
+
supervisor = run!(options)
|
46
|
+
|
47
|
+
# Take five, toplevel supervisor
|
48
|
+
sleep 5 while supervisor.alive? # Why 5?
|
49
|
+
|
50
|
+
Internals::Logger.error "!!! Celluloid::Supervision::Container #{self} crashed. Restarting..."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
finalizer :finalize
|
56
|
+
|
57
|
+
attr_accessor :registry
|
58
|
+
|
59
|
+
# Start the container.
|
60
|
+
def initialize(options = {})
|
61
|
+
options = { registry: options } if options.is_a? Internals::Registry
|
62
|
+
@state = :initializing
|
63
|
+
@actors = [] # instances in the container
|
64
|
+
@registry = options.delete(:registry) || Celluloid.actor_system.registry
|
65
|
+
@branch = options.delete(:branch) || :services
|
66
|
+
yield current_actor if block_given?
|
67
|
+
end
|
68
|
+
|
69
|
+
execute_block_on_receiver :initialize, :supervise, :supervise_as
|
70
|
+
|
71
|
+
def add(configuration)
|
72
|
+
Configuration.valid?(configuration, true)
|
73
|
+
@actors << Instance.new(configuration.merge(registry: @registry, branch: @branch))
|
74
|
+
@state = :running
|
75
|
+
add_accessors configuration
|
76
|
+
Actor.current
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_accessors(configuration)
|
80
|
+
if configuration[:as]
|
81
|
+
unless methods.include? configuration[:as]
|
82
|
+
self.class.instance_eval do
|
83
|
+
define_method(configuration[:as]) do
|
84
|
+
@registry[configuration[:as]]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def remove_accessors; end
|
92
|
+
|
93
|
+
def remove(actor)
|
94
|
+
actor = Celluloid::Actor[actor] if actor.is_a? Symbol
|
95
|
+
instance = find(actor)
|
96
|
+
instance.terminate if instance
|
97
|
+
end
|
98
|
+
|
99
|
+
def actors
|
100
|
+
@actors.map(&:actor)
|
101
|
+
end
|
102
|
+
|
103
|
+
def find(actor)
|
104
|
+
@actors.find do |instance|
|
105
|
+
instance.actor == actor
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def [](actor_name)
|
110
|
+
@registry[actor_name]
|
111
|
+
end
|
112
|
+
|
113
|
+
# Restart a crashed actor
|
114
|
+
def restart_actor(actor, reason)
|
115
|
+
return if @state == :shutdown
|
116
|
+
instance = find(actor)
|
117
|
+
raise "a container instance went missing. This shouldn't be!" unless instance
|
118
|
+
|
119
|
+
if reason
|
120
|
+
exclusive { instance.restart }
|
121
|
+
else
|
122
|
+
instance.cleanup
|
123
|
+
@actors.delete(instance)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def shutdown
|
128
|
+
@state = :shutdown
|
129
|
+
finalize
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def finalize
|
135
|
+
if @actors
|
136
|
+
@actors.reverse_each do |instance|
|
137
|
+
instance.terminate
|
138
|
+
@actors.delete(instance)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|