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
@@ -35,7 +35,7 @@ RSpec.shared_examples "a Celluloid Group" do
|
|
35
35
|
subject.get do
|
36
36
|
busy_queue << nil
|
37
37
|
@wait_queue.pop
|
38
|
-
|
38
|
+
raise exception_class, "Error"
|
39
39
|
end
|
40
40
|
|
41
41
|
wait_until_busy(busy_queue)
|
@@ -89,7 +89,7 @@ RSpec.shared_examples "a Celluloid Group" do
|
|
89
89
|
subject.get do
|
90
90
|
thread << Thread.current
|
91
91
|
sleep
|
92
|
-
end
|
92
|
+
end
|
93
93
|
).to be_a(Celluloid::Thread)
|
94
94
|
|
95
95
|
thread.pop # wait for 3rd-party thread to get strated
|
@@ -62,7 +62,7 @@ RSpec.shared_examples "a Celluloid Mailbox" do
|
|
62
62
|
subject << :first
|
63
63
|
subject << :second
|
64
64
|
subject << :third
|
65
|
-
expect(subject.to_a).to match_array([
|
65
|
+
expect(subject.to_a).to match_array(%i[first second])
|
66
66
|
end
|
67
67
|
|
68
68
|
it "logs discarded messages" do
|
@@ -0,0 +1,87 @@
|
|
1
|
+
RSpec.shared_examples "a Celluloid Stack" do
|
2
|
+
let(:actor_system) { Celluloid::Actor::System.new }
|
3
|
+
let(:threads) { Queue.new }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
items = 0
|
7
|
+
|
8
|
+
[Celluloid::Task::Fibered, Celluloid::Task::Threaded].each do |task_klass|
|
9
|
+
create_async_blocking_actor(task_klass)
|
10
|
+
items += 1
|
11
|
+
end
|
12
|
+
|
13
|
+
@active_thread = create_thread_with_role(threads, :other_thing)
|
14
|
+
items += 1
|
15
|
+
|
16
|
+
@idle_thread = create_thread_with_role(threads, :idle_thing)
|
17
|
+
items += 1
|
18
|
+
|
19
|
+
# StackWaiter for each thread to add itself to the queue
|
20
|
+
tmp = Queue.new
|
21
|
+
items.times do
|
22
|
+
th = Timeout.timeout(4) { threads.pop }
|
23
|
+
tmp << th
|
24
|
+
end
|
25
|
+
|
26
|
+
expect(threads).to be_empty
|
27
|
+
|
28
|
+
# put threads back into the queue for killing
|
29
|
+
threads << tmp.pop until tmp.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
after do
|
33
|
+
StackWaiter.no_longer
|
34
|
+
actor_system.shutdown
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#actors" do
|
38
|
+
it "should include all actors" do
|
39
|
+
expect(subject.actors.size).to eq(2)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#threads" do
|
44
|
+
# TODO: this spec should use mocks because it's non-deterministict
|
45
|
+
it "should include threads that are not actors" do
|
46
|
+
# TODO: Assess need for bypassing StackWaiter.forever's QUEUE.pop after #670 & #678
|
47
|
+
# NOTE: Pool#each doesn't guarantee to contain the newly started thread
|
48
|
+
# because the actor's methods (which create and store the thread handle)
|
49
|
+
# are started asynchronously.
|
50
|
+
#
|
51
|
+
# The mutexes in InternalPool especially can cause additional delay -
|
52
|
+
# causing Pool#get to wait for IPool#each to free the mutex before the
|
53
|
+
# new thread can be stored.
|
54
|
+
#
|
55
|
+
# And, Internals::StackDump#threads is cached, so we have to reconstruct the
|
56
|
+
# Internals::StackDump until it matches reality.
|
57
|
+
#
|
58
|
+
# Also, the actual number of threads and how InternalPool juggles them is
|
59
|
+
# non deterministic to begin with:
|
60
|
+
#
|
61
|
+
# 2 actors
|
62
|
+
# -> *0-1 task threads
|
63
|
+
#
|
64
|
+
# *1 idle thread
|
65
|
+
# *1 active thread
|
66
|
+
#
|
67
|
+
# Together: 3-4 threads
|
68
|
+
|
69
|
+
# Pool somehow doesn't create extra tasks
|
70
|
+
# 5 is on JRuby-head
|
71
|
+
expected = Celluloid.group_class == Celluloid::Group::Pool ? [3, 4] : [3, 4, 5, 6]
|
72
|
+
expect(expected).to include(subject.threads.size)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should include idle threads" do
|
76
|
+
expect(subject.threads.map(&:thread_id)).to include(@idle_thread.object_id)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should include threads checked out of the group for roles other than :actor" do
|
80
|
+
expect(subject.threads.map(&:thread_id)).to include(@active_thread.object_id)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have the correct roles" do
|
84
|
+
expect(subject.threads.map(&:role)).to include(:idle_thing, :other_thing)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -5,8 +5,7 @@ class MockActor
|
|
5
5
|
@tasks = []
|
6
6
|
end
|
7
7
|
|
8
|
-
def setup_thread
|
9
|
-
end
|
8
|
+
def setup_thread; end
|
10
9
|
end
|
11
10
|
|
12
11
|
RSpec.shared_examples "a Celluloid Task" do
|
@@ -41,7 +40,7 @@ RSpec.shared_examples "a Celluloid Task" do
|
|
41
40
|
|
42
41
|
it "raises exceptions outside" do
|
43
42
|
task = Celluloid.task_class.new(task_type, {}) do
|
44
|
-
|
43
|
+
raise "failure"
|
45
44
|
end
|
46
45
|
expect do
|
47
46
|
task.resume
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
RSpec.configure do |config|
|
2
|
-
config.filter_run focus: true unless Nenv.ci?
|
3
2
|
config.run_all_when_everything_filtered = true
|
4
3
|
config.disable_monkey_patching!
|
5
4
|
config.profile_examples = 3
|
@@ -19,7 +18,7 @@ RSpec.configure do |config|
|
|
19
18
|
config.before(:suite) do
|
20
19
|
Specs.stub_out_class_method(Celluloid::Internals::Logger, :crash) do |*args|
|
21
20
|
_name, ex = *args
|
22
|
-
|
21
|
+
raise "Unstubbed Logger.crash() was called:\n crash(\n #{args.map(&:inspect).join(",\n ")})"\
|
23
22
|
"\nException backtrace: \n (#{ex.class}) #{ex.backtrace * "\n (#{ex.class}) "}"
|
24
23
|
end
|
25
24
|
end
|
@@ -42,14 +41,14 @@ RSpec.configure do |config|
|
|
42
41
|
"\n** Crash: #{msg.inspect}(#{ex.inspect})\n Backtrace:\n (crash) #{call_stack * "\n (crash) "}"\
|
43
42
|
"\n Exception Backtrace (#{ex.inspect}):\n (ex) #{ex.backtrace * "\n (ex) "}"
|
44
43
|
end.join("\n")
|
45
|
-
|
44
|
+
raise "Actor crashes occurred (please stub/mock if these are expected): #{crashes}"
|
46
45
|
end
|
47
46
|
@fake_logger = nil
|
48
47
|
Specs.assert_no_loose_threads!("after example: #{ex.description}") if Specs::CHECK_LOOSE_THREADS
|
49
48
|
end
|
50
49
|
|
51
50
|
config.around :each, library: :IO do |ex|
|
52
|
-
Celluloid.
|
51
|
+
Celluloid.init
|
53
52
|
FileUtils.rm("/tmp/cell_sock") if File.exist?("/tmp/cell_sock")
|
54
53
|
ex.run
|
55
54
|
Celluloid.shutdown
|
data/spec/support/coverage.rb
CHANGED
@@ -19,7 +19,7 @@ module Specs
|
|
19
19
|
|
20
20
|
def crash(*args)
|
21
21
|
check
|
22
|
-
|
22
|
+
raise "Testing block has already ended!" if @details
|
23
23
|
@crashes << [args, caller.dup]
|
24
24
|
end
|
25
25
|
|
@@ -59,7 +59,7 @@ module Specs
|
|
59
59
|
def check
|
60
60
|
return if self.class.allowed_logger.first == self
|
61
61
|
|
62
|
-
|
62
|
+
raise "Incorrect logger used:"\
|
63
63
|
" active/allowed: \n#{clas.allowed_logger.inspect},\n"\
|
64
64
|
" actual/self: \n#{[self, @example].inspect}\n"\
|
65
65
|
" (maybe an actor from another test is still running?)"
|
@@ -45,7 +45,7 @@ module ExampleActorClass
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def crash
|
48
|
-
|
48
|
+
raise ExampleCrash, "the spec purposely crashed me :("
|
49
49
|
end
|
50
50
|
|
51
51
|
def crash_with_abort(reason, foo = nil)
|
@@ -89,11 +89,7 @@ module ExampleActorClass
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def respond_to?(method_name, include_private = false)
|
92
|
-
|
93
|
-
delegates?(method_name)
|
94
|
-
else
|
95
|
-
super
|
96
|
-
end
|
92
|
+
delegates?(method_name) || super
|
97
93
|
end
|
98
94
|
|
99
95
|
def method(method_name)
|
@@ -114,8 +110,7 @@ module ExampleActorClass
|
|
114
110
|
private :zomg_private
|
115
111
|
attr_reader :private_called
|
116
112
|
|
117
|
-
def my_finalizer
|
118
|
-
end
|
113
|
+
def my_finalizer; end
|
119
114
|
|
120
115
|
private
|
121
116
|
|
@@ -8,7 +8,7 @@ class CallExampleActor
|
|
8
8
|
def actual_method; end
|
9
9
|
|
10
10
|
def inspect
|
11
|
-
|
11
|
+
raise "Don't call!"
|
12
12
|
end
|
13
13
|
|
14
14
|
def chained_call_ids
|
@@ -28,7 +28,7 @@ class DeprecatedCallExampleActor
|
|
28
28
|
def actual_method; end
|
29
29
|
|
30
30
|
def inspect
|
31
|
-
|
31
|
+
raise "Please don't call me! I'm not ready yet!"
|
32
32
|
end
|
33
33
|
|
34
34
|
def chained_call_ids
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class SupervisionContainerHelper
|
2
|
+
@queue = nil
|
3
|
+
class << self
|
4
|
+
def reset!
|
5
|
+
@queue = Queue.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def done!
|
9
|
+
@queue << :done
|
10
|
+
end
|
11
|
+
|
12
|
+
def pop!
|
13
|
+
@queue.pop
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class MyContainerActor
|
19
|
+
include Celluloid
|
20
|
+
|
21
|
+
attr_reader :args
|
22
|
+
|
23
|
+
def initialize(*args)
|
24
|
+
@args = args
|
25
|
+
ready
|
26
|
+
end
|
27
|
+
|
28
|
+
def running?
|
29
|
+
:yep
|
30
|
+
end
|
31
|
+
|
32
|
+
def ready
|
33
|
+
SupervisionContainerHelper.done!
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class StackWaiter
|
2
|
+
QUEUE = Queue.new
|
3
|
+
WAITERS = Queue.new
|
4
|
+
ACTORS = Queue.new
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def forever
|
8
|
+
WAITERS << Thread.current
|
9
|
+
# de QUEUE.pop
|
10
|
+
sleep
|
11
|
+
end
|
12
|
+
|
13
|
+
def no_longer
|
14
|
+
StackWaiter::ACTORS.pop.terminate until StackWaiter::ACTORS.empty?
|
15
|
+
|
16
|
+
loop do
|
17
|
+
break if WAITERS.empty?
|
18
|
+
QUEUE << nil
|
19
|
+
nicely_end_thread(WAITERS.pop)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def nicely_end_thread(th)
|
24
|
+
return if jruby_fiber?(th)
|
25
|
+
|
26
|
+
status = th.status
|
27
|
+
case status
|
28
|
+
when nil, false, "dead"
|
29
|
+
when "aborting"
|
30
|
+
th.join(2) || STDERR.puts("Thread join timed out...")
|
31
|
+
when "sleep", "run"
|
32
|
+
th.kill
|
33
|
+
th.join(2) || STDERR.puts("Thread join timed out...")
|
34
|
+
else
|
35
|
+
STDERR.puts "unknown status: #{th.status.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def jruby_fiber?(th)
|
40
|
+
return false unless RUBY_PLATFORM == "java" && (java_th = th.to_java.getNativeThread)
|
41
|
+
/Fiber/ =~ java_th.get_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class StackBlocker
|
47
|
+
include Celluloid
|
48
|
+
|
49
|
+
def initialize(threads)
|
50
|
+
@threads = threads
|
51
|
+
end
|
52
|
+
|
53
|
+
def blocking
|
54
|
+
StackWaiter::ACTORS << Thread.current
|
55
|
+
@threads << Thread.current
|
56
|
+
StackWaiter.forever
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
def create_async_blocking_actor(task_klass)
|
2
|
+
actor_klass = Class.new(StackBlocker) do
|
3
|
+
task_class task_klass
|
4
|
+
end
|
5
|
+
|
6
|
+
actor = actor_system.within do
|
7
|
+
actor_klass.new(threads)
|
8
|
+
end
|
9
|
+
|
10
|
+
actor.async.blocking
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_thread_with_role(threads, role)
|
14
|
+
resume = Queue.new
|
15
|
+
thread = actor_system.get_thread do
|
16
|
+
resume.pop # to avoid race for 'thread' variable
|
17
|
+
thread.role = role
|
18
|
+
threads << thread
|
19
|
+
StackWaiter.forever
|
20
|
+
end
|
21
|
+
resume << nil # to avoid race for 'thread' variable
|
22
|
+
thread
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class SubordinateDead < Celluloid::Error; end
|
2
|
+
|
3
|
+
class Subordinate
|
4
|
+
include Celluloid
|
5
|
+
attr_reader :state
|
6
|
+
|
7
|
+
def initialize(state)
|
8
|
+
@state = state
|
9
|
+
end
|
10
|
+
|
11
|
+
def crack_the_whip
|
12
|
+
case @state
|
13
|
+
when :idle
|
14
|
+
@state = :working
|
15
|
+
else
|
16
|
+
raise SubordinateDead, "the spec purposely crashed me :("
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/support/logging.rb
CHANGED
@@ -1,21 +1,7 @@
|
|
1
1
|
module Specs
|
2
2
|
class << self
|
3
|
-
def log
|
4
|
-
# Setup ENV variable handling with sane defaults
|
5
|
-
@log ||= Nenv("celluloid_specs_log") do |env|
|
6
|
-
env.create_method(:file) { |f| f || "log/default.log" }
|
7
|
-
env.create_method(:sync?) { |s| s || !Nenv.ci? }
|
8
|
-
|
9
|
-
env.create_method(:strategy) do |strategy|
|
10
|
-
strategy || default_strategy
|
11
|
-
end
|
12
|
-
|
13
|
-
env.create_method(:level) { |level| default_level_for(env, level) }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
3
|
def logger
|
18
|
-
@logger ||= default_logger.tap { |
|
4
|
+
@logger ||= default_logger.tap { |log| log.level = Logger::WARN }
|
19
5
|
end
|
20
6
|
|
21
7
|
attr_writer :logger
|
@@ -23,33 +9,16 @@ module Specs
|
|
23
9
|
private
|
24
10
|
|
25
11
|
def default_logger
|
26
|
-
|
27
|
-
when "stderr"
|
28
|
-
Logger.new(STDERR)
|
29
|
-
when "single"
|
30
|
-
Logger.new(open_logfile(log.file, log.sync?))
|
31
|
-
else
|
32
|
-
fail "Unknown logger strategy: #{strategy.inspect}."\
|
33
|
-
" Expected 'single' or 'stderr'."
|
34
|
-
end
|
12
|
+
Logger.new(STDERR)
|
35
13
|
end
|
36
14
|
|
37
15
|
def open_logfile(rel_path, sync)
|
38
16
|
root = Pathname(__FILE__).dirname.dirname.dirname
|
39
17
|
log_path = root + rel_path
|
18
|
+
log_path.dirname.mkpath
|
40
19
|
logfile = File.open(log_path.to_s, "a")
|
41
20
|
logfile.sync if sync
|
42
21
|
logfile
|
43
22
|
end
|
44
|
-
|
45
|
-
def default_strategy
|
46
|
-
(Nenv.ci? ? "stderr" : "single")
|
47
|
-
end
|
48
|
-
|
49
|
-
def default_level_for(env, level)
|
50
|
-
Integer(level)
|
51
|
-
rescue
|
52
|
-
env.strategy == "stderr" ? Logger::WARN : Logger::DEBUG
|
53
|
-
end
|
54
23
|
end
|
55
24
|
end
|