celluloid 0.18.0.pre → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,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,7 +41,7 @@ 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
|
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,15 +9,7 @@ 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)
|
@@ -42,15 +20,5 @@ module Specs
|
|
42
20
|
logfile.sync if sync
|
43
21
|
logfile
|
44
22
|
end
|
45
|
-
|
46
|
-
def default_strategy
|
47
|
-
(Nenv.ci? ? "stderr" : "single")
|
48
|
-
end
|
49
|
-
|
50
|
-
def default_level_for(env, level)
|
51
|
-
Integer(level)
|
52
|
-
rescue
|
53
|
-
env.strategy == "stderr" ? Logger::WARN : Logger::DEBUG
|
54
|
-
end
|
55
23
|
end
|
56
24
|
end
|
@@ -13,20 +13,7 @@ module Specs
|
|
13
13
|
backtrace = thread.backtrace # avoid race maybe
|
14
14
|
next unless backtrace
|
15
15
|
next if backtrace.empty? # possibly a timer thread
|
16
|
-
|
17
|
-
|
18
|
-
if RUBY_ENGINE == "rbx"
|
19
|
-
# Avoid disrupting Rubinious thread
|
20
|
-
next if thread.backtrace.first =~ %r{rubysl/timeout/timeout\.rb}
|
21
|
-
|
22
|
-
if Specs::ALLOW_SLOW_MAILBOXES
|
23
|
-
if thread.backtrace.first =~ /wait/
|
24
|
-
next if thread.backtrace[1] =~ /mailbox\.rb/ && thread.backtrace[1] =~ /check/
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
if RUBY_ENGINE == "ruby"
|
16
|
+
else
|
30
17
|
# Sometimes stays
|
31
18
|
next if thread.backtrace.nil?
|
32
19
|
next unless thread.backtrace.is_a?(Array)
|
@@ -39,7 +26,7 @@ module Specs
|
|
39
26
|
end
|
40
27
|
|
41
28
|
def thread_name(thread)
|
42
|
-
|
29
|
+
RUBY_PLATFORM == "java" ? thread.to_java.getNativeThread.get_name : ""
|
43
30
|
end
|
44
31
|
|
45
32
|
def assert_no_loose_threads!(location)
|
@@ -61,7 +48,7 @@ module Specs
|
|
61
48
|
sleep
|
62
49
|
end
|
63
50
|
|
64
|
-
|
51
|
+
raise Celluloid::ThreadLeak, "Aborted due to runaway threads (#{location})\n"\
|
65
52
|
"List: (#{loose.map(&:inspect)})\n:#{backtraces.join("\n")}"
|
66
53
|
end
|
67
54
|
end
|