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.
- checksums.yaml +5 -5
- data/CHANGES.md +258 -39
- data/CONDUCT.md +13 -0
- data/CONTRIBUTING.md +39 -0
- data/README.md +54 -165
- 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 +72 -47
- data/lib/celluloid/actor.rb +27 -17
- data/lib/celluloid/actor/system.rb +13 -29
- data/lib/celluloid/autostart.rb +5 -5
- data/lib/celluloid/call/async.rb +2 -0
- data/lib/celluloid/call/sync.rb +10 -3
- data/lib/celluloid/calls.rb +5 -12
- 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 +7 -9
- data/lib/celluloid/group.rb +12 -8
- 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 -5
- 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 +9 -9
- data/lib/celluloid/proxy/async.rb +1 -1
- data/lib/celluloid/proxy/block.rb +2 -2
- data/lib/celluloid/proxy/cell.rb +1 -1
- data/lib/celluloid/proxy/future.rb +2 -4
- data/lib/celluloid/proxy/sync.rb +1 -3
- data/lib/celluloid/rspec.rb +22 -33
- 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 +11 -6
- data/lib/celluloid/task.rb +25 -12
- data/lib/celluloid/task/fibered.rb +2 -0
- 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 +2 -2
- 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 +11 -22
- 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 +30 -30
- 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 +58 -33
- 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 +2 -3
- 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 +2 -34
- data/spec/support/loose_threads.rb +3 -16
- data/spec/support/reset_class_variables.rb +5 -1
- data/spec/support/stubbing.rb +1 -1
- metadata +91 -323
- data/culture/CONDUCT.md +0 -38
- data/culture/GSoC/1010-why_we_will_participate.md +0 -17
- data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
- data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
- data/culture/GSoC/1040-getting_students_involved.md +0 -5
- data/culture/GSoC/1050-student_involvement_after.md +0 -5
- data/culture/GSoC/README.md +0 -16
- 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 -93
- 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 -61
- 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 -34
- data/lib/celluloid/fiber.rb +0 -32
- data/lib/celluloid/managed.rb +0 -3
- data/lib/celluloid/notices.rb +0 -15
- 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,43 @@
|
|
1
|
+
RSpec.describe Celluloid::Internals::Links do
|
2
|
+
subject { Celluloid::Internals::Links.new }
|
3
|
+
|
4
|
+
let(:mailbox_mock) do
|
5
|
+
Class.new(Array) do
|
6
|
+
attr_reader :address
|
7
|
+
def initialize(address)
|
8
|
+
@address = address
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:first_actor) do
|
14
|
+
Struct.new(:mailbox).new(mailbox_mock.new("foo123"))
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:second_actor) do
|
18
|
+
Struct.new(:mailbox).new(mailbox_mock.new("bar456"))
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is Enumerable" do
|
22
|
+
expect(subject).to be_an(Enumerable)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "adds actors by their mailbox address" do
|
26
|
+
expect(subject.include?(first_actor)).to be_falsey
|
27
|
+
subject << first_actor
|
28
|
+
expect(subject.include?(first_actor)).to be_truthy
|
29
|
+
end
|
30
|
+
|
31
|
+
it "removes actors by their mailbox address" do
|
32
|
+
subject << first_actor
|
33
|
+
expect(subject.include?(first_actor)).to be_truthy
|
34
|
+
subject.delete first_actor
|
35
|
+
expect(subject.include?(first_actor)).to be_falsey
|
36
|
+
end
|
37
|
+
|
38
|
+
it "iterates over all actors" do
|
39
|
+
subject << first_actor
|
40
|
+
subject << second_actor
|
41
|
+
expect(subject.inject([]) { |all, a| all << a }).to eq([first_actor, second_actor])
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
RSpec.describe Celluloid::Internals::Properties do
|
2
|
+
let(:default_value) { 42 }
|
3
|
+
let(:changed_value) { 43 }
|
4
|
+
|
5
|
+
let(:example_class) do
|
6
|
+
Class.new do
|
7
|
+
extend Celluloid::Internals::Properties
|
8
|
+
property :baz, default: 42
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:example_subclass) do
|
13
|
+
Class.new(example_class)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:example_subclass_subclass) do
|
17
|
+
Class.new(example_subclass)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "adds properties to classes" do
|
21
|
+
expect(example_class.baz).to eq default_value
|
22
|
+
example_class.baz changed_value
|
23
|
+
expect(example_class.baz).to eq changed_value
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows properties to be inherited" do
|
27
|
+
expect(example_subclass.baz).to eq default_value
|
28
|
+
example_subclass.baz changed_value
|
29
|
+
expect(example_subclass.baz).to eq changed_value
|
30
|
+
expect(example_class.baz).to eq default_value
|
31
|
+
end
|
32
|
+
|
33
|
+
it "allows properties to be deeply inherited" do
|
34
|
+
expect(example_subclass_subclass.baz).to eq default_value
|
35
|
+
example_subclass_subclass.baz changed_value
|
36
|
+
expect(example_subclass_subclass.baz).to eq changed_value
|
37
|
+
expect(example_subclass.baz).to eq default_value
|
38
|
+
expect(example_class.baz).to eq default_value
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
RSpec.describe Celluloid::Internals::Registry, actor_system: :global do
|
2
|
+
class Marilyn
|
3
|
+
include Celluloid
|
4
|
+
|
5
|
+
def sing_for(person)
|
6
|
+
"o/~ Happy birthday, #{person}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "registers Actors" do
|
11
|
+
Celluloid::Actor[:marilyn] = Marilyn.new
|
12
|
+
expect(Celluloid::Actor[:marilyn].sing_for("Mr. President")).to eq("o/~ Happy birthday, Mr. President")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "refuses to register non-Actors" do
|
16
|
+
expect do
|
17
|
+
Celluloid::Actor[:impostor] = Object.new
|
18
|
+
end.to raise_error TypeError
|
19
|
+
end
|
20
|
+
|
21
|
+
it "lists all registered actors" do
|
22
|
+
Celluloid::Actor[:marilyn] = Marilyn.new
|
23
|
+
expect(Celluloid::Actor.registered).to include :marilyn
|
24
|
+
end
|
25
|
+
|
26
|
+
it "knows its name once registered" do
|
27
|
+
Celluloid::Actor[:marilyn] = Marilyn.new
|
28
|
+
expect(Celluloid::Actor[:marilyn].registered_name).to eq(:marilyn)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe :delete do
|
32
|
+
before do
|
33
|
+
Celluloid::Actor[:marilyn] ||= Marilyn.new
|
34
|
+
end
|
35
|
+
|
36
|
+
it "removes reference to actors' name from the registry" do
|
37
|
+
Celluloid::Actor.delete(:marilyn)
|
38
|
+
expect(Celluloid::Actor.registered).not_to include :marilyn
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns actor removed from the registry" do
|
42
|
+
rval = Celluloid::Actor.delete(:marilyn)
|
43
|
+
expect(rval).to be_kind_of(Marilyn)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe :clear do
|
48
|
+
it "should return a hash of registered actors and remove them from the registry" do
|
49
|
+
Celluloid::Actor[:marilyn] ||= Marilyn.new
|
50
|
+
rval = Celluloid::Actor.clear_registry
|
51
|
+
begin
|
52
|
+
expect(rval).to be_kind_of(Hash)
|
53
|
+
expect(rval).to have_key(:marilyn)
|
54
|
+
expect(rval[:marilyn].wrapped_object).to be_instance_of(Marilyn)
|
55
|
+
expect(Celluloid::Actor.registered).to be_empty
|
56
|
+
ensure
|
57
|
+
# Repopulate the registry once we're done
|
58
|
+
rval.each { |key, actor| Celluloid::Actor[key] = actor }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
RSpec.describe Celluloid::Internals::ThreadHandle do
|
2
|
+
let(:actor_system) { Celluloid::Actor::System.new }
|
3
|
+
after { actor_system.shutdown }
|
4
|
+
|
5
|
+
context "given a living thread" do
|
6
|
+
let(:args) { [actor_system] }
|
7
|
+
|
8
|
+
before do
|
9
|
+
@thread = nil
|
10
|
+
@thread_info_queue = Queue.new
|
11
|
+
@handle = Celluloid::Internals::ThreadHandle.new(*args) do
|
12
|
+
@thread_info_queue << Thread.current
|
13
|
+
sleep
|
14
|
+
end
|
15
|
+
@thread = Timeout.timeout(2) { @thread_info_queue.pop }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "knows the thread is alive" do
|
19
|
+
alive = @handle.alive?
|
20
|
+
if @thread
|
21
|
+
@thread.kill
|
22
|
+
@thread.join
|
23
|
+
else
|
24
|
+
STDERR.puts "NOTE: something failed - thread missing"
|
25
|
+
end
|
26
|
+
expect(alive).to be(true)
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when a role is provided" do
|
30
|
+
let(:args) { [actor_system, :useful] }
|
31
|
+
|
32
|
+
it "can be retrieved from thread directly" do
|
33
|
+
role = @thread.role
|
34
|
+
if @thread
|
35
|
+
@thread.kill
|
36
|
+
@thread.join
|
37
|
+
else
|
38
|
+
STDERR.puts "NOTE: something failed - thread missing"
|
39
|
+
end
|
40
|
+
expect(role).to eq(:useful)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "given a finished thread" do
|
46
|
+
before do
|
47
|
+
thread_info_queue = Queue.new
|
48
|
+
@handle = Celluloid::Internals::ThreadHandle.new(actor_system) do
|
49
|
+
thread_info_queue << Thread.current
|
50
|
+
end
|
51
|
+
thread = thread_info_queue.pop
|
52
|
+
thread.kill
|
53
|
+
Specs.sleep_and_wait_until { !thread.alive? }
|
54
|
+
end
|
55
|
+
|
56
|
+
it "knows the thread is no longer alive" do
|
57
|
+
expect(@handle).not_to be_alive
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec.describe Celluloid::Internals::UUID do
|
2
|
+
U = Celluloid::Internals::UUID
|
3
|
+
|
4
|
+
it "generates unique IDs across the BLOCK_SIZE boundary" do
|
5
|
+
upper_bound = U::BLOCK_SIZE * 2 + 10
|
6
|
+
uuids = (1..upper_bound).map { U.generate }
|
7
|
+
expect(uuids.size).to eq(uuids.uniq.size)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
RSpec.describe Celluloid::RingBuffer do
|
2
|
+
subject { Celluloid::RingBuffer.new(2) }
|
3
|
+
|
4
|
+
it { is_expected.to be_empty }
|
5
|
+
it { is_expected.not_to be_full }
|
6
|
+
|
7
|
+
it "should push and shift" do
|
8
|
+
subject.push("foo")
|
9
|
+
subject.push("foo2")
|
10
|
+
expect(subject.shift).to eq("foo")
|
11
|
+
expect(subject.shift).to eq("foo2")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should push past the end" do
|
15
|
+
subject.push("foo")
|
16
|
+
subject.push("foo2")
|
17
|
+
subject.push("foo3")
|
18
|
+
expect(subject).to be_full
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should shift the most recent" do
|
22
|
+
(1..5).each { |i| subject.push(i) }
|
23
|
+
expect(subject.shift).to be 4
|
24
|
+
expect(subject.shift).to be 5
|
25
|
+
expect(subject.shift).to be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return nil when shifting empty" do
|
29
|
+
expect(subject).to be_empty
|
30
|
+
expect(subject.shift).to be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be thread-safe" do
|
34
|
+
# TODO: how to test?
|
35
|
+
end
|
36
|
+
end
|
@@ -2,36 +2,25 @@ 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
|
-
|
25
|
-
end
|
14
|
+
expect(Time.now - started_at).to be_within(Specs::TIMER_QUANTUM).of timeout_interval
|
26
15
|
end
|
27
16
|
|
28
17
|
it "discard messages when reactor wakeup fails" do
|
29
|
-
expect(Celluloid::Internals::Logger).to receive(:crash).with(
|
18
|
+
expect(Celluloid::Internals::Logger).to receive(:crash).with("reactor crashed", RuntimeError)
|
30
19
|
expect(Celluloid.logger).to receive(:debug).with("Discarded message (mailbox is dead): first")
|
31
20
|
|
32
21
|
bad_reactor = Class.new do
|
33
22
|
def wakeup
|
34
|
-
|
23
|
+
raise
|
35
24
|
end
|
36
25
|
end
|
37
26
|
mailbox = Celluloid::Mailbox::Evented.new(bad_reactor)
|
@@ -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
|