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
@@ -2,26 +2,28 @@ RSpec.describe Celluloid::Mailbox::Evented do
|
|
2
2
|
subject { TestEventedMailbox.new }
|
3
3
|
it_behaves_like "a Celluloid Mailbox"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
unless RUBY_ENGINE == "rbx"
|
15
|
-
it "recovers from timeout exceeded to process mailbox message" do
|
16
|
-
timeout_interval = Specs::TIMER_QUANTUM + 0.1
|
17
|
-
started_at = Time.now
|
18
|
-
expect do
|
19
|
-
Kernel.send(:timeout, timeout_interval) do
|
20
|
-
subject.receive { false }
|
21
|
-
end
|
22
|
-
end.to raise_exception(Timeout::Error)
|
5
|
+
it "recovers from timeout exceeded to process mailbox message" do
|
6
|
+
timeout_interval = Specs::TIMER_QUANTUM + 0.1
|
7
|
+
started_at = Time.now
|
8
|
+
expect do
|
9
|
+
::Timeout.timeout(timeout_interval) do
|
10
|
+
subject.receive { false }
|
11
|
+
end
|
12
|
+
end.to raise_exception(Timeout::Error)
|
23
13
|
|
24
|
-
|
14
|
+
expect(Time.now - started_at).to be_within(Specs::TIMER_QUANTUM).of timeout_interval
|
15
|
+
end
|
16
|
+
|
17
|
+
it "discard messages when reactor wakeup fails" do
|
18
|
+
expect(Celluloid::Internals::Logger).to receive(:crash).with("reactor crashed", RuntimeError)
|
19
|
+
expect(Celluloid.logger).to receive(:debug).with("Discarded message (mailbox is dead): first")
|
20
|
+
|
21
|
+
bad_reactor = Class.new do
|
22
|
+
def wakeup
|
23
|
+
raise
|
24
|
+
end
|
25
25
|
end
|
26
|
+
mailbox = Celluloid::Mailbox::Evented.new(bad_reactor)
|
27
|
+
mailbox << :first
|
26
28
|
end
|
27
29
|
end
|
@@ -13,11 +13,10 @@ RSpec.describe "Leaks", actor_system: :global, leaktest: true,
|
|
13
13
|
[]
|
14
14
|
end
|
15
15
|
|
16
|
-
def terminate
|
17
|
-
end
|
16
|
+
def terminate; end
|
18
17
|
end
|
19
18
|
|
20
|
-
def wait_for_release(weak, _what, count=1000)
|
19
|
+
def wait_for_release(weak, _what, count = 1000)
|
21
20
|
trash = []
|
22
21
|
count.times do |step|
|
23
22
|
GC.start
|
@@ -43,7 +42,7 @@ RSpec.describe "Leaks", actor_system: :global, leaktest: true,
|
|
43
42
|
end
|
44
43
|
|
45
44
|
context "celluloid actor" do
|
46
|
-
|
45
|
+
xit "is properly destroyed upon termination" do
|
47
46
|
actor_life("actor") do |actor|
|
48
47
|
WeakRef.new actor
|
49
48
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
RSpec.describe Celluloid::Notifications, actor_system: :global do
|
2
|
+
class Admirer
|
3
|
+
include Celluloid
|
4
|
+
include Celluloid::Notifications
|
5
|
+
|
6
|
+
attr_reader :mourning
|
7
|
+
attr_reader :mourning_count
|
8
|
+
|
9
|
+
def someone_died(_topic, name)
|
10
|
+
@mourning = name
|
11
|
+
@mourning_count ||= 0
|
12
|
+
@mourning_count += 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class President
|
17
|
+
include Celluloid
|
18
|
+
include Celluloid::Notifications
|
19
|
+
|
20
|
+
def die(topic = "death")
|
21
|
+
publish(topic, "Mr. President")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "notifies relevant subscribers" do
|
26
|
+
marilyn = Admirer.new
|
27
|
+
jackie = Admirer.new
|
28
|
+
|
29
|
+
marilyn.subscribe("death", :someone_died)
|
30
|
+
jackie.subscribe("alive", :someone_died)
|
31
|
+
|
32
|
+
president = President.new
|
33
|
+
|
34
|
+
president.die
|
35
|
+
expect(marilyn.mourning).to eq("Mr. President")
|
36
|
+
expect(jackie.mourning).not_to eq("Mr. President")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "allows multiple subscriptions from the same actor" do
|
40
|
+
marilyn = Admirer.new
|
41
|
+
|
42
|
+
marilyn.subscribe("death", :someone_died)
|
43
|
+
marilyn.subscribe("death", :someone_died)
|
44
|
+
|
45
|
+
president = President.new
|
46
|
+
|
47
|
+
president.die
|
48
|
+
expect(marilyn.mourning_count).to be(2)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "notifies subscribers" do
|
52
|
+
marilyn = Admirer.new
|
53
|
+
jackie = Admirer.new
|
54
|
+
|
55
|
+
marilyn.subscribe("death", :someone_died)
|
56
|
+
jackie.subscribe("death", :someone_died)
|
57
|
+
|
58
|
+
president = President.new
|
59
|
+
|
60
|
+
president.die
|
61
|
+
expect(marilyn.mourning).to eq("Mr. President")
|
62
|
+
expect(jackie.mourning).to eq("Mr. President")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "publishes even if there are no subscribers" do
|
66
|
+
president = President.new
|
67
|
+
president.die
|
68
|
+
end
|
69
|
+
|
70
|
+
it "allows symbol subscriptions" do
|
71
|
+
marilyn = Admirer.new
|
72
|
+
jackie = Admirer.new
|
73
|
+
|
74
|
+
marilyn.subscribe(:death, :someone_died)
|
75
|
+
jackie.subscribe("death", :someone_died)
|
76
|
+
|
77
|
+
president = President.new
|
78
|
+
president.die(:death)
|
79
|
+
expect(marilyn.mourning).to eq("Mr. President")
|
80
|
+
expect(jackie.mourning).to eq("Mr. President")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "allows regex subscriptions" do
|
84
|
+
marilyn = Admirer.new
|
85
|
+
|
86
|
+
marilyn.subscribe(/(death|assassination)/, :someone_died)
|
87
|
+
|
88
|
+
president = President.new
|
89
|
+
president.die
|
90
|
+
expect(marilyn.mourning).to eq("Mr. President")
|
91
|
+
end
|
92
|
+
|
93
|
+
it "matches symbols against regex subscriptions" do
|
94
|
+
marilyn = Admirer.new
|
95
|
+
|
96
|
+
marilyn.subscribe(/(death|assassination)/, :someone_died)
|
97
|
+
|
98
|
+
president = President.new
|
99
|
+
president.die(:assassination)
|
100
|
+
expect(marilyn.mourning).to eq("Mr. President")
|
101
|
+
end
|
102
|
+
|
103
|
+
it "allows unsubscribing" do
|
104
|
+
marilyn = Admirer.new
|
105
|
+
|
106
|
+
subscription = marilyn.subscribe("death", :someone_died)
|
107
|
+
marilyn.unsubscribe(subscription)
|
108
|
+
|
109
|
+
president = President.new
|
110
|
+
president.die
|
111
|
+
expect(marilyn.mourning).to be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
it "prunes dead subscriptions" do
|
115
|
+
marilyn = Admirer.new
|
116
|
+
jackie = Admirer.new
|
117
|
+
|
118
|
+
marilyn.subscribe("death", :someone_died)
|
119
|
+
jackie.subscribe("death", :someone_died)
|
120
|
+
|
121
|
+
listeners = Celluloid::Notifications.notifier.listeners_for("death").size
|
122
|
+
marilyn.terminate
|
123
|
+
after_listeners = Celluloid::Notifications.notifier.listeners_for("death").size
|
124
|
+
|
125
|
+
expect(after_listeners).to eq(listeners - 1)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "prunes multiple subscriptions from a dead actor" do
|
129
|
+
marilyn = Admirer.new
|
130
|
+
|
131
|
+
marilyn.subscribe("death", :someone_died)
|
132
|
+
marilyn.subscribe("death", :someone_died)
|
133
|
+
|
134
|
+
listeners = Celluloid::Notifications.notifier.listeners_for("death").size
|
135
|
+
marilyn.terminate
|
136
|
+
after_listeners = Celluloid::Notifications.notifier.listeners_for("death").size
|
137
|
+
|
138
|
+
expect(after_listeners).to eq(listeners - 2)
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "celluloid/probe"
|
2
|
+
|
3
|
+
class DummyActor; include Celluloid; end
|
4
|
+
|
5
|
+
class TestProbeClient
|
6
|
+
include Celluloid
|
7
|
+
include Celluloid::Notifications
|
8
|
+
|
9
|
+
attr_reader :buffer
|
10
|
+
finalizer :do_unsubscribe
|
11
|
+
|
12
|
+
def initialize(queue)
|
13
|
+
@events = queue
|
14
|
+
subscribe(/celluloid\.events\..+/, :event_received)
|
15
|
+
end
|
16
|
+
|
17
|
+
def event_received(topic, args)
|
18
|
+
@events << [topic, args[0], args[1]]
|
19
|
+
end
|
20
|
+
|
21
|
+
def do_unsubscribe
|
22
|
+
# TODO: shouldn't be necessary
|
23
|
+
return unless Actor[:notifications_fanout]
|
24
|
+
|
25
|
+
unsubscribe
|
26
|
+
rescue Celluloid::DeadActorError
|
27
|
+
# Something is wrong with the shutdown seq. Whatever...
|
28
|
+
rescue => ex
|
29
|
+
STDERR.puts "Exception while finalizing TestProbeClient: #{ex.inspect}"
|
30
|
+
STDERR.puts "BACKTRACE: #{ex.backtrace * "\n (ex) "}"
|
31
|
+
sleep 5
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec.describe "Probe", actor_system: :global do
|
36
|
+
let(:logger) { Specs::FakeLogger.current }
|
37
|
+
|
38
|
+
def addr(actor)
|
39
|
+
return nil unless actor
|
40
|
+
return nil unless actor.mailbox
|
41
|
+
return nil unless actor.mailbox.address
|
42
|
+
actor.mailbox.address
|
43
|
+
rescue Celluloid::DeadActorError
|
44
|
+
"(dead actor)"
|
45
|
+
end
|
46
|
+
|
47
|
+
def wait_for_match(queue, topic, actor1 = nil, actor2 = nil)
|
48
|
+
started = Time.now.to_f
|
49
|
+
actors = [actor1, actor2]
|
50
|
+
expected = ([topic] + actors.map { |a| addr(a) }).dup
|
51
|
+
|
52
|
+
received = []
|
53
|
+
last_event_timestamp = nil
|
54
|
+
|
55
|
+
Timeout.timeout(5) do
|
56
|
+
loop do
|
57
|
+
event = queue.pop
|
58
|
+
actual = ([event[0]] + event[1..-1].map { |a| addr(a) }).dup
|
59
|
+
received << actual
|
60
|
+
last_event_timestamp = Time.now.to_f
|
61
|
+
return event if actual == expected
|
62
|
+
end
|
63
|
+
end
|
64
|
+
rescue Timeout::Error => e
|
65
|
+
q = Celluloid::Probe::EVENTS_BUFFER
|
66
|
+
unprocessed = []
|
67
|
+
loop do
|
68
|
+
break if q.empty?
|
69
|
+
name, args = q.pop
|
70
|
+
actual = ([name] + args.map { |a| addr(a) }).dup
|
71
|
+
unprocessed << actual
|
72
|
+
end
|
73
|
+
|
74
|
+
last_event_offset = if last_event_timestamp
|
75
|
+
last_event_timestamp - started
|
76
|
+
else
|
77
|
+
"(no events ever received)"
|
78
|
+
end
|
79
|
+
|
80
|
+
raise "wait_for_match: no matching event received for #{topic.inspect}! (#{e.inspect})\n"\
|
81
|
+
"Expected: #{expected.inspect}\n"\
|
82
|
+
"Events received: \n #{received.map(&:inspect) * "\n "}\n"\
|
83
|
+
"Current time offset: #{(Time.now.to_f - started).inspect}\n"\
|
84
|
+
"Last event offset: #{last_event_offset.inspect}\n"\
|
85
|
+
"Unprocessed probe events: #{unprocessed.map(&:inspect) * "\n "}\n"\
|
86
|
+
end
|
87
|
+
|
88
|
+
def flush_probe_queue
|
89
|
+
# Probe doesn't process the queue periodically, so some events can get in
|
90
|
+
# while previous events are being processed.
|
91
|
+
#
|
92
|
+
# So, we generate another event, so Probe processed the queue (containing
|
93
|
+
# the previously unprocessed event).
|
94
|
+
Celluloid::Actor["an_extra_event"] = Class.new { include Celluloid }.new
|
95
|
+
end
|
96
|
+
|
97
|
+
let(:queue) { Queue.new }
|
98
|
+
|
99
|
+
describe ".run" do
|
100
|
+
pending "cannot unsupervise the Probe yet (#573)"
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec.describe Celluloid::Proxy::Abstract do
|
2
|
+
around do |ex|
|
3
|
+
Celluloid.boot
|
4
|
+
ex.run
|
5
|
+
Celluloid.shutdown
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:task_klass) { Celluloid.task_class }
|
9
|
+
let(:actor_class) { ExampleActorClass.create(CelluloidSpecs.included_module, task_klass) }
|
10
|
+
let(:actor) { actor_class.new "Troy McClure" }
|
11
|
+
|
12
|
+
let(:logger) { Specs::FakeLogger.current }
|
13
|
+
|
14
|
+
it "should be eql? to self" do
|
15
|
+
expect(actor.eql?(actor)).to be_truthy
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be eql? to self even if dead" do
|
19
|
+
actor.terminate
|
20
|
+
expect(actor.eql?(actor)).to be_truthy
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not be eql? to other proxy objects" do
|
24
|
+
other_future = Celluloid::Proxy::Future.new(actor.mailbox, actor.__klass__)
|
25
|
+
|
26
|
+
expect(actor.future.eql?(other_future)).to be_truthy
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be possible to compare with non-proxy objects" do
|
30
|
+
expect(actor.eql?("string")).to be_falsey
|
31
|
+
expect("string".eql?(actor)).to be_falsey
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
RSpec.describe Celluloid::Supervision::Container::Behavior do
|
2
|
+
class WellBehaved
|
3
|
+
include Celluloid
|
4
|
+
end
|
5
|
+
|
6
|
+
let(:typeless) do
|
7
|
+
{
|
8
|
+
as: :testing_behaviors,
|
9
|
+
supervises: [
|
10
|
+
{
|
11
|
+
as: :testing_behaved_instances,
|
12
|
+
type: WellBehaved
|
13
|
+
}
|
14
|
+
]
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:normal) do
|
19
|
+
{
|
20
|
+
as: :testing_behaviors,
|
21
|
+
supervises: [
|
22
|
+
{
|
23
|
+
as: :testing_behaved_instances,
|
24
|
+
type: WellBehaved
|
25
|
+
}
|
26
|
+
]
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:mutant) do
|
31
|
+
{
|
32
|
+
as: :testing_behaviors,
|
33
|
+
supervise: [],
|
34
|
+
supervises: [
|
35
|
+
{
|
36
|
+
as: :testing_behaved_instances,
|
37
|
+
type: WellBehaved
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
subject { Celluloid::Supervision::Configuration.new }
|
44
|
+
|
45
|
+
it("detects default type if not provided, and provides it") do
|
46
|
+
end
|
47
|
+
|
48
|
+
it("prejudicially rejects mutants") do
|
49
|
+
expect { subject.define(mutant) }.to raise_error(Celluloid::Supervision::Container::Behavior::Error::Mutant)
|
50
|
+
end
|
51
|
+
|
52
|
+
context("allows definition of new plugins") do
|
53
|
+
class TestPlugin
|
54
|
+
include Celluloid::Supervision::Container::Behavior
|
55
|
+
identifier! :identifying_parameter, :aliased_identifier
|
56
|
+
end
|
57
|
+
|
58
|
+
xit("and adds a plugin parameter") do
|
59
|
+
expect(Celluloid::Supervision::Configuration.parameters(:plugins)).to include(:identifying_parameter)
|
60
|
+
end
|
61
|
+
|
62
|
+
xit("and adds aliased parameters") do
|
63
|
+
expect(Celluloid::Supervision::Configuration.aliases.keys?).to include(:aliased_identifier)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context("allows inclusion by Module") do
|
68
|
+
xit("with automatic addition of injections") do
|
69
|
+
end
|
70
|
+
|
71
|
+
xit("with correct handling of injections made") do
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
RSpec.describe Celluloid::Supervision::Configuration, actor_system: :global do
|
2
|
+
class TestActor
|
3
|
+
include Celluloid
|
4
|
+
def identity
|
5
|
+
:testing
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:succeeding) do
|
10
|
+
{
|
11
|
+
as: :testing,
|
12
|
+
type: TestActor
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:failing) do
|
17
|
+
{
|
18
|
+
as: :testing,
|
19
|
+
type: TestActor,
|
20
|
+
args: [:fail]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
Celluloid::Supervision::Configuration.resync_parameters
|
26
|
+
subject.resync_accessors
|
27
|
+
end
|
28
|
+
|
29
|
+
context("remains reusable without being mutated") do
|
30
|
+
it("properly") do
|
31
|
+
expect(Celluloid.actor_system.root_configuration.export).to eq(Celluloid::Actor::System::ROOT_SERVICES)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context("metaprogramming") do
|
36
|
+
context("Celluloid.services accessor") do
|
37
|
+
it("is dynamically added, and available") do
|
38
|
+
expect(Celluloid.services.respond_to?(:supervise)).to be_truthy
|
39
|
+
end
|
40
|
+
it("allows supervision") do
|
41
|
+
Celluloid.services.supervise(type: TestActor, as: :test_actor)
|
42
|
+
expect(Celluloid.services.test_actor.identity).to eq(:testing)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context("supervised actors can create accessors") do
|
47
|
+
it("which are dynamically added, and available as Celluloid.accessor") do
|
48
|
+
TestActor.supervise(as: :test_actor, accessors: [:test_actor])
|
49
|
+
expect(Celluloid.test_actor.identity).to eq(:testing)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context("parameters") do
|
55
|
+
context("can be added to") do
|
56
|
+
context("can be given new :mandatory parameters") do
|
57
|
+
before(:each) do
|
58
|
+
Celluloid::Supervision::Configuration.parameter! :mandatory, :special_requirement
|
59
|
+
subject.resync_accessors
|
60
|
+
end
|
61
|
+
|
62
|
+
it("programmatically") do
|
63
|
+
expect(Celluloid::Supervision::Configuration.parameters(:mandatory)).to include(:special_requirement)
|
64
|
+
end
|
65
|
+
|
66
|
+
it("and respond appropriately") do
|
67
|
+
subject.resync_accessors
|
68
|
+
expect(subject.methods).to include(:special_requirement)
|
69
|
+
expect(subject.respond_to?(:special_requirement!)).to be_truthy
|
70
|
+
expect(subject.respond_to?(:special_requirement?)).to be_truthy
|
71
|
+
expect(subject.respond_to?(:special_requirement=)).to be_truthy
|
72
|
+
expect(subject.respond_to?(:special_requirement)).to be_truthy
|
73
|
+
end
|
74
|
+
|
75
|
+
it("and instances will respond appropriately") do
|
76
|
+
subject.instances.first.resync_accessors
|
77
|
+
subject.define(type: TestActor, special_requirement: :valid)
|
78
|
+
expect(subject.respond_to?(:special_requirement)).to be_truthy
|
79
|
+
end
|
80
|
+
|
81
|
+
it("and be reset to defaults") do
|
82
|
+
Celluloid::Supervision::Configuration.resync_parameters
|
83
|
+
expect(Celluloid::Supervision::Configuration.parameters(:mandatory)).not_to include(:special_requirement)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context("can be aliased") do
|
88
|
+
before(:each) do
|
89
|
+
Celluloid::Supervision::Configuration.resync_parameters
|
90
|
+
Celluloid::Supervision::Configuration.alias! :nick, :as
|
91
|
+
subject.resync_accessors
|
92
|
+
end
|
93
|
+
|
94
|
+
it("programmatically") do
|
95
|
+
expect(Celluloid::Supervision::Configuration.aliases.keys).to include(:nick)
|
96
|
+
end
|
97
|
+
|
98
|
+
it("and respond appropriately by method") do
|
99
|
+
subject.define(type: TestActor, as: :test_name)
|
100
|
+
expect(subject.respond_to?(:nick!)).to be_truthy
|
101
|
+
expect(subject.respond_to?(:nick?)).to be_truthy
|
102
|
+
expect(subject.respond_to?(:nick=)).to be_truthy
|
103
|
+
expect(subject.respond_to?(:nick)).to be_truthy
|
104
|
+
expect(subject.nick).to eq(:test_name)
|
105
|
+
end
|
106
|
+
|
107
|
+
xit("and respond properly by current_instance, by method") do
|
108
|
+
# subject.current_instance[:aliased] gets subject.current_instance[:original]
|
109
|
+
end
|
110
|
+
|
111
|
+
it("and instances will respond properly by method") do
|
112
|
+
subject.define(as: :test_name, type: TestActor)
|
113
|
+
expect(subject.instances.first.respond_to?(:nick!)).to be_truthy
|
114
|
+
expect(subject.instances.first.respond_to?(:nick?)).to be_truthy
|
115
|
+
expect(subject.instances.first.respond_to?(:nick=)).to be_truthy
|
116
|
+
expect(subject.instances.first.respond_to?(:nick)).to be_truthy
|
117
|
+
expect(subject.instances.first.nick).to eq(:test_name)
|
118
|
+
end
|
119
|
+
|
120
|
+
xit("and respond appropriately by key") do
|
121
|
+
# subject[:aliased] gets subject[:original]
|
122
|
+
end
|
123
|
+
|
124
|
+
xit("and instances respond properly by current_instance, by key") do
|
125
|
+
# subject.instances.first[:aliased] gets subject.instances.first[:original]
|
126
|
+
end
|
127
|
+
|
128
|
+
xit("and instances respond properly by key") do
|
129
|
+
# subject.instances.first[:aliased] gets subject.instances.first[:original]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context("Configuration.define class method") do
|
136
|
+
xit("can take individual instance configuration") do
|
137
|
+
end
|
138
|
+
|
139
|
+
xit("can take array of instance configurations") do
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context("Configuration#define instance method") do
|
144
|
+
xit("can take individual instance configuration") do
|
145
|
+
end
|
146
|
+
|
147
|
+
xit("can take array of instance configurations") do
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context("Configuration.deploy class method") do
|
152
|
+
xit("can take individual instance configuration") do
|
153
|
+
end
|
154
|
+
|
155
|
+
xit("can take array of instance configurations") do
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context("Configuration#deploy instance method") do
|
160
|
+
xit("can take individual instance configuration") do
|
161
|
+
end
|
162
|
+
|
163
|
+
xit("can take array of instance configurations") do
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context("accessing information") do
|
168
|
+
before(:each) { subject.define(succeeding) }
|
169
|
+
it("can get values out of current level of configuration by [:key]") do
|
170
|
+
expect(subject[:as]).to eq(:testing)
|
171
|
+
end
|
172
|
+
|
173
|
+
it("can get values out of current level of configuration by #key") do
|
174
|
+
expect(subject.as).to eq(:testing)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
it("verifies arity of intended actor's initialize method") do
|
179
|
+
expect { subject.define(failing) }.to raise_exception(ArgumentError)
|
180
|
+
end
|
181
|
+
end
|