celluloid 0.16.0 → 0.17.3

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.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +394 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +28 -15
  5. data/culture/CONDUCT.md +28 -0
  6. data/culture/Gemfile +9 -0
  7. data/culture/LICENSE.txt +22 -0
  8. data/culture/README.md +22 -0
  9. data/culture/Rakefile +5 -0
  10. data/culture/SYNC.md +70 -0
  11. data/culture/celluloid-culture.gemspec +18 -0
  12. data/culture/gems/README.md +39 -0
  13. data/culture/gems/dependencies.yml +85 -0
  14. data/culture/gems/loader.rb +101 -0
  15. data/culture/rubocop/README.md +38 -0
  16. data/culture/rubocop/lint.yml +8 -0
  17. data/culture/rubocop/metrics.yml +15 -0
  18. data/culture/rubocop/perf.yml +0 -0
  19. data/culture/rubocop/rubocop.yml +5 -0
  20. data/culture/rubocop/style.yml +57 -0
  21. data/culture/spec/gems_spec.rb +2 -0
  22. data/culture/spec/spec_helper.rb +0 -0
  23. data/culture/spec/sync_spec.rb +2 -0
  24. data/culture/sync.rb +56 -0
  25. data/culture/tasks/rspec.rake +5 -0
  26. data/culture/tasks/rubocop.rake +2 -0
  27. data/examples/basic_usage.rb +49 -0
  28. data/examples/futures.rb +38 -0
  29. data/examples/ring.rb +61 -0
  30. data/examples/simple_pmap.rb +14 -0
  31. data/examples/stack.rb +47 -0
  32. data/examples/timers.rb +72 -0
  33. data/lib/celluloid/actor/manager.rb +7 -0
  34. data/lib/celluloid/actor/system.rb +163 -0
  35. data/lib/celluloid/actor.rb +53 -71
  36. data/lib/celluloid/autostart.rb +1 -1
  37. data/lib/celluloid/backported.rb +2 -0
  38. data/lib/celluloid/call/async.rb +16 -0
  39. data/lib/celluloid/call/block.rb +22 -0
  40. data/lib/celluloid/call/sync.rb +70 -0
  41. data/lib/celluloid/calls.rb +24 -114
  42. data/lib/celluloid/cell.rb +32 -20
  43. data/lib/celluloid/condition.rb +5 -6
  44. data/lib/celluloid/core_ext.rb +1 -1
  45. data/lib/celluloid/current.rb +2 -0
  46. data/lib/celluloid/debug.rb +1 -0
  47. data/lib/celluloid/deprecate.rb +21 -0
  48. data/lib/celluloid/exceptions.rb +22 -16
  49. data/lib/celluloid/fiber.rb +3 -3
  50. data/lib/celluloid/future.rb +46 -8
  51. data/lib/celluloid/group/pool.rb +125 -0
  52. data/lib/celluloid/group/spawner.rb +68 -0
  53. data/lib/celluloid/group.rb +61 -0
  54. data/lib/celluloid/logging.rb +5 -5
  55. data/lib/celluloid/mailbox/evented.rb +74 -0
  56. data/lib/celluloid/mailbox.rb +15 -14
  57. data/lib/celluloid/managed.rb +3 -0
  58. data/lib/celluloid/notices.rb +15 -0
  59. data/lib/celluloid/proxies.rb +11 -0
  60. data/lib/celluloid/proxy/abstract.rb +50 -0
  61. data/lib/celluloid/proxy/actor.rb +37 -0
  62. data/lib/celluloid/proxy/async.rb +15 -0
  63. data/lib/celluloid/proxy/block.rb +28 -0
  64. data/lib/celluloid/proxy/cell.rb +66 -0
  65. data/lib/celluloid/proxy/future.rb +20 -0
  66. data/lib/celluloid/proxy/sync.rb +24 -0
  67. data/lib/celluloid/rspec.rb +67 -9
  68. data/lib/celluloid/system_events.rb +69 -14
  69. data/lib/celluloid/task/fibered.rb +45 -0
  70. data/lib/celluloid/task/threaded.rb +59 -0
  71. data/lib/celluloid/{tasks.rb → task.rb} +30 -38
  72. data/lib/celluloid/test.rb +1 -1
  73. data/lib/celluloid/thread.rb +6 -1
  74. data/lib/celluloid/version.rb +3 -0
  75. data/lib/celluloid.rb +151 -130
  76. data/spec/celluloid/actor/system_spec.rb +83 -0
  77. data/spec/celluloid/actor_spec.rb +2 -2
  78. data/spec/celluloid/block_spec.rb +67 -8
  79. data/spec/celluloid/calls_spec.rb +28 -23
  80. data/spec/celluloid/condition_spec.rb +23 -14
  81. data/spec/celluloid/evented_mailbox_spec.rb +1 -31
  82. data/spec/celluloid/future_spec.rb +15 -12
  83. data/spec/celluloid/group/elastic_spec.rb +0 -0
  84. data/spec/celluloid/group/pool_spec.rb +8 -0
  85. data/spec/celluloid/group/spawner_spec.rb +17 -0
  86. data/spec/celluloid/mailbox/evented_spec.rb +40 -0
  87. data/spec/celluloid/mailbox_spec.rb +1 -3
  88. data/spec/celluloid/misc/leak_spec.rb +73 -0
  89. data/spec/celluloid/proxy_spec.rb +33 -0
  90. data/spec/celluloid/task/fibered_spec.rb +5 -0
  91. data/spec/celluloid/task/threaded_spec.rb +5 -0
  92. data/spec/celluloid/timer_spec.rb +14 -16
  93. data/spec/deprecate/actor_system_spec.rb +72 -0
  94. data/spec/deprecate/block_spec.rb +52 -0
  95. data/spec/deprecate/calls_spec.rb +39 -0
  96. data/spec/deprecate/evented_mailbox_spec.rb +34 -0
  97. data/spec/deprecate/future_spec.rb +32 -0
  98. data/spec/deprecate/internal_pool_spec.rb +4 -0
  99. data/spec/shared/actor_examples.rb +1259 -0
  100. data/spec/shared/group_examples.rb +121 -0
  101. data/spec/shared/mailbox_examples.rb +87 -0
  102. data/{lib/celluloid/rspec → spec/shared}/task_examples.rb +9 -8
  103. data/spec/spec_helper.rb +5 -42
  104. data/spec/support/configure_rspec.rb +77 -0
  105. data/spec/support/coverage.rb +4 -0
  106. data/spec/support/crash_checking.rb +68 -0
  107. data/spec/support/debugging.rb +31 -0
  108. data/spec/support/env.rb +21 -0
  109. data/{lib/celluloid/rspec/example_actor_class.rb → spec/support/examples/actor_class.rb} +21 -2
  110. data/spec/support/examples/call_class.rb +37 -0
  111. data/spec/support/examples/evented_mailbox_class.rb +27 -0
  112. data/spec/support/includer.rb +6 -0
  113. data/spec/support/logging.rb +55 -0
  114. data/spec/support/loose_threads.rb +68 -0
  115. data/spec/support/reset_class_variables.rb +27 -0
  116. data/spec/support/sleep_and_wait.rb +14 -0
  117. data/spec/support/stubbing.rb +14 -0
  118. metadata +276 -78
  119. data/lib/celluloid/actor_system.rb +0 -107
  120. data/lib/celluloid/call_chain.rb +0 -13
  121. data/lib/celluloid/cpu_counter.rb +0 -34
  122. data/lib/celluloid/evented_mailbox.rb +0 -73
  123. data/lib/celluloid/fsm.rb +0 -186
  124. data/lib/celluloid/handlers.rb +0 -41
  125. data/lib/celluloid/internal_pool.rb +0 -159
  126. data/lib/celluloid/legacy.rb +0 -9
  127. data/lib/celluloid/links.rb +0 -36
  128. data/lib/celluloid/logger.rb +0 -93
  129. data/lib/celluloid/logging/incident.rb +0 -21
  130. data/lib/celluloid/logging/incident_logger.rb +0 -129
  131. data/lib/celluloid/logging/incident_reporter.rb +0 -48
  132. data/lib/celluloid/logging/log_event.rb +0 -20
  133. data/lib/celluloid/logging/ring_buffer.rb +0 -65
  134. data/lib/celluloid/method.rb +0 -32
  135. data/lib/celluloid/notifications.rb +0 -83
  136. data/lib/celluloid/pool_manager.rb +0 -146
  137. data/lib/celluloid/probe.rb +0 -73
  138. data/lib/celluloid/properties.rb +0 -24
  139. data/lib/celluloid/proxies/abstract_proxy.rb +0 -20
  140. data/lib/celluloid/proxies/actor_proxy.rb +0 -38
  141. data/lib/celluloid/proxies/async_proxy.rb +0 -31
  142. data/lib/celluloid/proxies/block_proxy.rb +0 -29
  143. data/lib/celluloid/proxies/cell_proxy.rb +0 -68
  144. data/lib/celluloid/proxies/future_proxy.rb +0 -35
  145. data/lib/celluloid/proxies/sync_proxy.rb +0 -36
  146. data/lib/celluloid/receivers.rb +0 -63
  147. data/lib/celluloid/registry.rb +0 -57
  148. data/lib/celluloid/responses.rb +0 -44
  149. data/lib/celluloid/rspec/actor_examples.rb +0 -1054
  150. data/lib/celluloid/rspec/mailbox_examples.rb +0 -84
  151. data/lib/celluloid/signals.rb +0 -23
  152. data/lib/celluloid/stack_dump.rb +0 -133
  153. data/lib/celluloid/supervision_group.rb +0 -169
  154. data/lib/celluloid/supervisor.rb +0 -22
  155. data/lib/celluloid/task_set.rb +0 -49
  156. data/lib/celluloid/tasks/task_fiber.rb +0 -43
  157. data/lib/celluloid/tasks/task_thread.rb +0 -53
  158. data/lib/celluloid/thread_handle.rb +0 -50
  159. data/lib/celluloid/uuid.rb +0 -38
  160. data/spec/celluloid/actor_system_spec.rb +0 -69
  161. data/spec/celluloid/cpu_counter_spec.rb +0 -82
  162. data/spec/celluloid/fsm_spec.rb +0 -107
  163. data/spec/celluloid/internal_pool_spec.rb +0 -52
  164. data/spec/celluloid/links_spec.rb +0 -45
  165. data/spec/celluloid/logging/ring_buffer_spec.rb +0 -38
  166. data/spec/celluloid/notifications_spec.rb +0 -120
  167. data/spec/celluloid/pool_spec.rb +0 -92
  168. data/spec/celluloid/probe_spec.rb +0 -121
  169. data/spec/celluloid/properties_spec.rb +0 -42
  170. data/spec/celluloid/registry_spec.rb +0 -64
  171. data/spec/celluloid/stack_dump_spec.rb +0 -64
  172. data/spec/celluloid/supervision_group_spec.rb +0 -65
  173. data/spec/celluloid/supervisor_spec.rb +0 -103
  174. data/spec/celluloid/tasks/task_fiber_spec.rb +0 -5
  175. data/spec/celluloid/tasks/task_thread_spec.rb +0 -5
  176. data/spec/celluloid/thread_handle_spec.rb +0 -26
  177. data/spec/celluloid/uuid_spec.rb +0 -11
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::ActorSystem do
4
- class TestActor
5
- include Celluloid
6
- end
7
-
8
- it "supports non-global ActorSystem" do
9
- subject.within do
10
- Celluloid.actor_system.should == subject
11
- end
12
- end
13
-
14
- it "starts default actors" do
15
- subject.start
16
-
17
- subject.registered.should == [:notifications_fanout, :default_incident_reporter]
18
- end
19
-
20
- it "support getting threads" do
21
- queue = Queue.new
22
- thread = subject.get_thread do
23
- Celluloid.actor_system.should == subject
24
- queue << nil
25
- end
26
- queue.pop
27
- end
28
-
29
- it "allows a stack dump" do
30
- subject.stack_dump.should be_a(Celluloid::StackDump)
31
- end
32
-
33
- it "returns named actors" do
34
- subject.registered.should be_empty
35
-
36
- subject.within do
37
- TestActor.supervise_as :test
38
- end
39
-
40
- subject.registered.should == [:test]
41
- end
42
-
43
- it "returns running actors" do
44
- subject.running.should be_empty
45
-
46
- first = subject.within do
47
- TestActor.new
48
- end
49
-
50
- second = subject.within do
51
- TestActor.new
52
- end
53
-
54
- subject.running.should == [first, second]
55
- end
56
-
57
- it "shuts down" do
58
- subject.shutdown
59
-
60
- lambda { subject.get_thread }.
61
- should raise_error("Thread pool is not running")
62
- end
63
-
64
- it "warns nicely when no actor system is started" do
65
- lambda { TestActor.new }.
66
- should raise_error("Celluloid is not yet started; use Celluloid.boot")
67
- end
68
-
69
- end
@@ -1,82 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::CPUCounter do
4
- describe :cores do
5
- subject { described_class.cores }
6
-
7
- let(:num_cores) { 1024 }
8
-
9
- before do
10
- described_class.stub(:`) { fail 'backtick stub called' }
11
- ::IO.stub(:open).and_raise('IO.open stub called!')
12
- described_class.instance_variable_set('@cores', nil)
13
- end
14
-
15
- after { ENV['NUMBER_OF_PROCESSORS'] = nil }
16
-
17
- context 'from valid env value' do
18
- before { ENV['NUMBER_OF_PROCESSORS'] = num_cores.to_s }
19
- it { should eq num_cores }
20
- end
21
-
22
- context 'from invalid env value' do
23
- before { ENV['NUMBER_OF_PROCESSORS'] = '' }
24
- specify { expect { subject }.to raise_error(ArgumentError) }
25
- end
26
-
27
- context 'with no env value' do
28
- before { ENV['NUMBER_OF_PROCESSORS'] = nil }
29
-
30
- context 'when /sys/devices/system/cpu/present exists' do
31
- before do
32
- ::IO.should_receive(:read).with('/sys/devices/system/cpu/present')
33
- .and_return("dunno-whatever-#{num_cores - 1}")
34
- end
35
- it { should eq num_cores }
36
- end
37
-
38
- context 'when /sys/devices/system/cpu/present does NOT exist' do
39
- before do
40
- ::IO.should_receive(:read).with('/sys/devices/system/cpu/present')
41
- .and_raise(Errno::ENOENT)
42
- end
43
-
44
- context 'when /sys/devices/system/cpu/cpu* files exist' do
45
- before do
46
- cpu_entries = (1..num_cores).map { |n| "cpu#{n}" }
47
- cpu_entries << 'non-cpu-entry-to-ignore'
48
- Dir.should_receive(:[]).with('/sys/devices/system/cpu/cpu*')
49
- .and_return(cpu_entries)
50
- end
51
- it { should eq num_cores }
52
- end
53
-
54
- context 'when /sys/devices/system/cpu/cpu* files DO NOT exist' do
55
- before do
56
- Dir.should_receive(:[]).with('/sys/devices/system/cpu/cpu*')
57
- .and_return([])
58
- end
59
-
60
- context 'when sysctl blows up' do
61
- before { described_class.stub(:`).and_raise(Errno::EINTR) }
62
- specify { expect { subject }.to raise_error }
63
- end
64
-
65
- context 'when sysctl fails' do
66
- before { described_class.stub(:`).and_return(`false`) }
67
- it { should be nil }
68
- end
69
-
70
- context 'when sysctl succeeds' do
71
- before do
72
- described_class.should_receive(:`).with('sysctl -n hw.ncpu')
73
- .and_return(num_cores.to_s)
74
- `true`
75
- end
76
- it { should eq num_cores }
77
- end
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,107 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::FSM, actor_system: :global do
4
- before :all do
5
- class TestMachine
6
- include Celluloid::FSM
7
-
8
- def initialize
9
- super
10
- @fired = false
11
- end
12
-
13
- state :callbacked do
14
- @fired = true
15
- end
16
-
17
- state :pre_done, :to => :done
18
- state :another, :done
19
-
20
- def fired?; @fired end
21
- end
22
-
23
- class DummyActor
24
- include Celluloid
25
- end
26
-
27
- class CustomDefaultMachine
28
- include Celluloid::FSM
29
-
30
- default_state :foobar
31
- end
32
- end
33
-
34
- subject { TestMachine.new }
35
-
36
- it "starts in the default state" do
37
- subject.state.should eq(TestMachine.default_state)
38
- end
39
-
40
- it "transitions between states" do
41
- subject.state.should_not be :done
42
- subject.transition :done
43
- subject.state.should be :done
44
- end
45
-
46
- it "fires callbacks for states" do
47
- subject.should_not be_fired
48
- subject.transition :callbacked
49
- subject.should be_fired
50
- end
51
-
52
- it "allows custom default states" do
53
- CustomDefaultMachine.new.state.should be :foobar
54
- end
55
-
56
- it "supports constraints on valid state transitions" do
57
- subject.transition :pre_done
58
- expect { subject.transition :another }.to raise_exception ArgumentError
59
- end
60
-
61
- it "transitions to states after a specified delay" do
62
- interval = Celluloid::TIMER_QUANTUM * 10
63
-
64
- subject.attach DummyActor.new
65
- subject.transition :another
66
- subject.transition :done, :delay => interval
67
-
68
- subject.state.should be :another
69
- sleep interval + Celluloid::TIMER_QUANTUM
70
-
71
- subject.state.should be :done
72
- end
73
-
74
- it "cancels delayed state transitions if another transition is made" do
75
- interval = Celluloid::TIMER_QUANTUM * 10
76
-
77
- subject.attach DummyActor.new
78
- subject.transition :another
79
- subject.transition :done, :delay => interval
80
-
81
- subject.state.should be :another
82
- subject.transition :pre_done
83
- sleep interval + Celluloid::TIMER_QUANTUM
84
-
85
- subject.state.should be :pre_done
86
- end
87
-
88
- context "actor is not set" do
89
- context "transition is delayed" do
90
- it "raises an unattached error" do
91
- expect { subject.transition :another, :delay => 100 } \
92
- .to raise_error(Celluloid::FSM::UnattachedError)
93
- end
94
- end
95
- end
96
-
97
- context "transitioning to an invalid state" do
98
- it "raises an argument error" do
99
- expect { subject.transition :invalid_state }.to raise_error(ArgumentError)
100
- end
101
-
102
- it "should not call transition! if the state is :default" do
103
- subject.should_not_receive :transition!
104
- subject.transition :default
105
- end
106
- end
107
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::InternalPool do
4
- it "gets threads from the pool" do
5
- subject.get { sleep 1 }.should be_a Thread
6
- end
7
-
8
- it "puts threads back into the pool" do
9
- subject.idle_size.should be_zero
10
- subject.busy_size.should be_zero
11
-
12
- queue = Queue.new
13
- subject.get { queue.pop }
14
-
15
- subject.idle_size.should be_zero
16
- subject.busy_size.should eq 1
17
-
18
- queue << nil
19
- sleep 0.01 # hax
20
-
21
- subject.idle_size.should eq 1
22
- subject.busy_size.should eq 0
23
- end
24
-
25
- it "cleans thread locals from old threads" do
26
- thread = subject.get { Thread.current[:foo] = :bar }
27
-
28
- sleep 0.01 #hax
29
- thread[:foo].should be_nil
30
- end
31
-
32
- it "doesn't fail if a third-party thread is spawned" do
33
- subject.idle_size.should be_zero
34
- subject.busy_size.should be_zero
35
-
36
- subject.get { ::Thread.new { sleep 0.5 } }.should be_a(Celluloid::Thread)
37
-
38
- sleep 0.01 # hax
39
-
40
- subject.idle_size.should eq 1
41
- subject.busy_size.should eq 0
42
- end
43
-
44
- it "doesn't leak dead threads" do
45
- subject.max_idle = 0 # Instruct the pool to immediately shut down the thread.
46
- subject.get { true }.should be_a(Celluloid::Thread)
47
-
48
- sleep 0.01 # hax
49
-
50
- subject.to_a.should have(0).items
51
- end
52
- end
@@ -1,45 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::Links do
4
- subject { Celluloid::Links.new }
5
-
6
- let(:mailbox_mock) do
7
- Class.new(Array) do
8
- attr_reader :address
9
- def initialize address
10
- @address = address
11
- end
12
- end
13
- end
14
-
15
- let(:first_actor) do
16
- Struct.new(:mailbox).new(mailbox_mock.new('foo123'))
17
- end
18
-
19
- let(:second_actor) do
20
- Struct.new(:mailbox).new(mailbox_mock.new('bar456'))
21
- end
22
-
23
- it 'is Enumerable' do
24
- subject.should be_an(Enumerable)
25
- end
26
-
27
- it 'adds actors by their mailbox address' do
28
- subject.include?(first_actor).should be_false
29
- subject << first_actor
30
- subject.include?(first_actor).should be_true
31
- end
32
-
33
- it 'removes actors by their mailbox address' do
34
- subject << first_actor
35
- subject.include?(first_actor).should be_true
36
- subject.delete first_actor
37
- subject.include?(first_actor).should be_false
38
- end
39
-
40
- it 'iterates over all actors' do
41
- subject << first_actor
42
- subject << second_actor
43
- subject.inject([]) { |all, a| all << a }.should == [first_actor, second_actor]
44
- end
45
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::RingBuffer do
4
- subject { Celluloid::RingBuffer.new(2) }
5
-
6
- it { should be_empty }
7
- it { should_not be_full }
8
-
9
- it 'should push and shift' do
10
- subject.push('foo')
11
- subject.push('foo2')
12
- subject.shift.should eq('foo')
13
- subject.shift.should eq('foo2')
14
- end
15
-
16
- it 'should push past the end' do
17
- subject.push('foo')
18
- subject.push('foo2')
19
- subject.push('foo3')
20
- subject.should be_full
21
- end
22
-
23
- it 'should shift the most recent' do
24
- (1..5).each { |i| subject.push(i) }
25
- subject.shift.should be 4
26
- subject.shift.should be 5
27
- subject.shift.should be_nil
28
- end
29
-
30
- it 'should return nil when shifting empty' do
31
- subject.should be_empty
32
- subject.shift.should be_nil
33
- end
34
-
35
- it 'should be thread-safe' do
36
- #TODO how to test?
37
- end
38
- end
@@ -1,120 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::Notifications, actor_system: :global do
4
- class Admirer
5
- include Celluloid
6
- include Celluloid::Notifications
7
-
8
- attr_reader :mourning
9
- attr_reader :mourning_count
10
-
11
- def someone_died(topic, name)
12
- @mourning = name
13
- @mourning_count ||= 0
14
- @mourning_count += 1
15
- end
16
- end
17
-
18
- class President
19
- include Celluloid
20
- include Celluloid::Notifications
21
-
22
- def die
23
- publish("death", "Mr. President")
24
- end
25
- end
26
-
27
- it 'notifies relevant subscribers' do
28
- marilyn = Admirer.new
29
- jackie = Admirer.new
30
-
31
- marilyn.subscribe("death", :someone_died)
32
- jackie.subscribe("alive", :someone_died)
33
-
34
- president = President.new
35
-
36
- president.die
37
- marilyn.mourning.should eq("Mr. President")
38
- jackie.mourning.should_not eq("Mr. President")
39
- end
40
-
41
- it 'allows multiple subscriptions from the same actor' do
42
- marilyn = Admirer.new
43
-
44
- marilyn.subscribe("death", :someone_died)
45
- marilyn.subscribe("death", :someone_died)
46
-
47
- president = President.new
48
-
49
- president.die
50
- marilyn.mourning_count.should be(2)
51
- end
52
-
53
-
54
- it 'notifies subscribers' do
55
- marilyn = Admirer.new
56
- jackie = Admirer.new
57
-
58
- marilyn.subscribe("death", :someone_died)
59
- jackie.subscribe("death", :someone_died)
60
-
61
- president = President.new
62
-
63
- president.die
64
- marilyn.mourning.should eq("Mr. President")
65
- jackie.mourning.should eq("Mr. President")
66
- end
67
-
68
- it 'publishes even if there are no subscribers' do
69
- president = President.new
70
- president.die
71
- end
72
-
73
- it 'allows regex subscriptions' do
74
- marilyn = Admirer.new
75
-
76
- marilyn.subscribe(/(death|assassination)/, :someone_died)
77
-
78
- president = President.new
79
- president.die
80
- marilyn.mourning.should eq("Mr. President")
81
- end
82
-
83
- it 'allows unsubscribing' do
84
- marilyn = Admirer.new
85
-
86
- subscription = marilyn.subscribe("death", :someone_died)
87
- marilyn.unsubscribe(subscription)
88
-
89
- president = President.new
90
- president.die
91
- marilyn.mourning.should be_nil
92
- end
93
-
94
- it 'prunes dead subscriptions' do
95
- marilyn = Admirer.new
96
- jackie = Admirer.new
97
-
98
- marilyn.subscribe("death", :someone_died)
99
- jackie.subscribe("death", :someone_died)
100
-
101
- listeners = Celluloid::Notifications.notifier.listeners_for("death").size
102
- marilyn.terminate
103
- after_listeners = Celluloid::Notifications.notifier.listeners_for("death").size
104
-
105
- after_listeners.should == listeners - 1
106
- end
107
-
108
- it 'prunes multiple subscriptions from a dead actor' do
109
- marilyn = Admirer.new
110
-
111
- marilyn.subscribe("death", :someone_died)
112
- marilyn.subscribe("death", :someone_died)
113
-
114
- listeners = Celluloid::Notifications.notifier.listeners_for("death").size
115
- marilyn.terminate
116
- after_listeners = Celluloid::Notifications.notifier.listeners_for("death").size
117
-
118
- after_listeners.should eq(listeners - 2)
119
- end
120
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Celluloid.pool", actor_system: :global do
4
- class ExampleError < StandardError; end
5
-
6
- class MyWorker
7
- include Celluloid
8
-
9
- def process(queue = nil)
10
- if queue
11
- queue << :done
12
- else
13
- :done
14
- end
15
- end
16
-
17
- def sleepy_work
18
- t = Time.now.to_f
19
- sleep 0.25
20
- t
21
- end
22
-
23
- def crash
24
- raise ExampleError, "zomgcrash"
25
- end
26
- end
27
-
28
- def test_concurrency_of(pool)
29
- baseline = Time.now.to_f
30
- values = 10.times.map { pool.future.sleepy_work }.map(&:value)
31
- values.select {|t| t - baseline < 0.1 }.length
32
- end
33
-
34
- subject { MyWorker.pool }
35
-
36
- it "processes work units synchronously" do
37
- subject.process.should be :done
38
- end
39
-
40
- it "processes work units asynchronously" do
41
- queue = Queue.new
42
- subject.async.process(queue)
43
- queue.pop.should be :done
44
- end
45
-
46
- it "handles crashes" do
47
- expect { subject.crash }.to raise_error(ExampleError)
48
- subject.process.should be :done
49
- end
50
-
51
- it "uses a fixed-sized number of threads" do
52
- subject # eagerly evaluate the pool to spawn it
53
-
54
- actors = Celluloid::Actor.all
55
- 100.times.map { subject.future(:process) }.map(&:value)
56
-
57
- new_actors = Celluloid::Actor.all - actors
58
- new_actors.should eq []
59
- end
60
-
61
- it "terminates" do
62
- expect { subject.terminate }.to_not raise_exception
63
- end
64
-
65
- it "handles many requests" do
66
- futures = 10.times.map do
67
- subject.future.process
68
- end
69
- futures.map(&:value)
70
- end
71
-
72
- context "#size=" do
73
- subject { MyWorker.pool size: 4 }
74
-
75
- it "should adjust the pool size up", pending: 'flaky' do
76
- expect(test_concurrency_of(subject)).to eq(4)
77
-
78
- subject.size = 6
79
- subject.size.should == 6
80
-
81
- test_concurrency_of(subject).should == 6
82
- end
83
-
84
- it "should adjust the pool size down" do
85
- test_concurrency_of(subject).should == 4
86
-
87
- subject.size = 2
88
- subject.size.should == 2
89
- test_concurrency_of(subject).should == 2
90
- end
91
- end
92
- end