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,42 +1,47 @@
1
- require 'spec_helper'
1
+ RSpec.describe Celluloid::Call::Sync, actor_system: :global do
2
+ # TODO: these should be Call::Sync unit tests (without working on actual actors)
2
3
 
3
- describe Celluloid::SyncCall, actor_system: :global do
4
- class CallExampleActor
5
- include Celluloid
6
-
7
- def initialize(next_actor = nil)
8
- @next = next_actor
4
+ let(:actor) { CallExampleActor.new }
5
+ let(:logger) { Specs::FakeLogger.current }
6
+
7
+ context "when obj does not respond to a method" do
8
+ # bypass this until rubinius/rubinius#3373 is resolved
9
+ # under Rubinius, `method` calls `inspect` on an object when a method is not found
10
+ unless RUBY_ENGINE == "rbx"
11
+ it "raises a NoMethodError" do
12
+ allow(logger).to receive(:crash).with("Actor crashed!", NoMethodError)
13
+
14
+ expect do
15
+ actor.the_method_that_wasnt_there
16
+ end.to raise_exception(NoMethodError)
17
+ end
9
18
  end
10
19
 
11
- def actual_method; end
20
+ context "when obj raises during inspect" do
21
+ it "should emulate obj.inspect" do
22
+ allow(logger).to receive(:crash).with("Actor crashed!", NoMethodError)
12
23
 
13
- def chained_call_ids
14
- [call_chain_id, @next.call_chain_id]
24
+ if RUBY_ENGINE == "rbx"
25
+ expected = /undefined method `no_such_method' on an instance of CallExampleActor/
26
+ else
27
+ expected = /undefined method `no_such_method' for #\<CallExampleActor:0x[a-f0-9]+\>/
28
+ end
29
+ end
15
30
  end
16
31
  end
17
32
 
18
- let(:actor) { CallExampleActor.new }
19
-
20
- it "aborts with NoMethodError when a nonexistent method is called" do
21
- expect do
22
- actor.the_method_that_wasnt_there
23
- end.to raise_exception(NoMethodError)
24
-
25
- actor.should be_alive
26
- end
27
-
28
33
  it "aborts with ArgumentError when a method is called with too many arguments" do
34
+ allow(logger).to receive(:crash).with("Actor crashed!", ArgumentError)
35
+
29
36
  expect do
30
37
  actor.actual_method("with too many arguments")
31
38
  end.to raise_exception(ArgumentError)
32
-
33
- actor.should be_alive
34
39
  end
35
40
 
36
41
  it "preserves call chains across synchronous calls" do
37
42
  actor2 = CallExampleActor.new(actor)
38
43
 
39
44
  uuid, next_actor_uuid = actor2.chained_call_ids
40
- uuid.should eq next_actor_uuid
45
+ expect(uuid).to eq next_actor_uuid
41
46
  end
42
47
  end
@@ -1,6 +1,6 @@
1
- require 'spec_helper'
1
+ RSpec.describe Celluloid::Condition, actor_system: :global do
2
+ let(:logger) { Specs::FakeLogger.current }
2
3
 
3
- describe Celluloid::Condition, actor_system: :global do
4
4
  class ConditionExample
5
5
  include Celluloid
6
6
 
@@ -9,7 +9,7 @@ describe Celluloid::Condition, actor_system: :global do
9
9
  def initialize
10
10
  @condition = Condition.new
11
11
 
12
- @waiting = false
12
+ @waiting = false
13
13
  @signaled_times = 0
14
14
  end
15
15
 
@@ -29,7 +29,9 @@ describe Celluloid::Condition, actor_system: :global do
29
29
  value
30
30
  end
31
31
 
32
- def waiting?; @waiting end
32
+ def waiting?
33
+ @waiting
34
+ end
33
35
  end
34
36
 
35
37
  let(:actor) { ConditionExample.new }
@@ -37,40 +39,47 @@ describe Celluloid::Condition, actor_system: :global do
37
39
 
38
40
  it "sends signals" do
39
41
  3.times { actor.async.wait_for_condition }
40
- actor.signaled_times.should be_zero
42
+ expect(actor.signaled_times).to be_zero
41
43
 
42
44
  actor.condition.signal
43
- actor.signaled_times.should be(1)
45
+ expect(actor.signaled_times).to be(1)
44
46
  end
45
47
 
46
48
  it "broadcasts signals" do
47
49
  3.times { actor.async.wait_for_condition }
48
- actor.signaled_times.should be_zero
50
+ expect(actor.signaled_times).to be_zero
49
51
 
50
52
  actor.condition.broadcast
51
- actor.signaled_times.should be(3)
53
+ expect(actor.signaled_times).to be(3)
52
54
  end
53
55
 
54
56
  it "sends values along with signals" do
55
57
  future = actor.future(:wait_for_condition)
56
58
  actor.condition.signal(:example_value)
57
- future.value.should be(:example_value)
59
+ expect(future.value).to be(:example_value)
60
+ end
61
+
62
+ it "supports running blocks with value once obtained" do
63
+ condition = Celluloid::Condition.new
64
+ actor.async.signal_condition condition, :value
65
+ expect(condition.wait { |value| "#{value} post-handled" }).to eq("value post-handled")
58
66
  end
59
67
 
60
68
  it "supports waiting outside actors" do
61
69
  condition = Celluloid::Condition.new
62
70
  actor.async.signal_condition condition, :value
63
- condition.wait.should eq(:value)
71
+ expect(condition.wait).to eq(:value)
64
72
  end
65
73
 
66
74
  it "times out inside normal Threads" do
67
75
  condition = Celluloid::Condition.new
68
- lambda { condition.wait(1) }.
69
- should raise_error(Celluloid::ConditionError)
76
+ expect { condition.wait(1) }
77
+ .to raise_error(Celluloid::ConditionError)
70
78
  end
71
79
 
72
80
  it "times out inside Tasks" do
73
- lambda { actor.wait_for_condition(1) }.
74
- should raise_error(Celluloid::ConditionError)
81
+ allow(logger).to receive(:crash).with("Actor crashed!", Celluloid::ConditionError)
82
+ expect { actor.wait_for_condition(1) }
83
+ .to raise_error(Celluloid::ConditionError)
75
84
  end
76
85
  end
@@ -1,34 +1,4 @@
1
- require 'spec_helper'
2
-
3
- class TestEventedMailbox < Celluloid::EventedMailbox
4
- class Reactor
5
- def initialize
6
- @condition = ConditionVariable.new
7
- @mutex = Mutex.new
8
- end
9
-
10
- def wakeup
11
- @mutex.synchronize do
12
- @condition.signal
13
- end
14
- end
15
-
16
- def run_once(timeout)
17
- @mutex.synchronize do
18
- @condition.wait(@mutex, timeout)
19
- end
20
- end
21
-
22
- def shutdown
23
- end
24
- end
25
-
26
- def initialize
27
- super(Reactor)
28
- end
29
- end
30
-
31
- describe Celluloid::EventedMailbox do
1
+ RSpec.describe Celluloid::Mailbox::Evented do
32
2
  subject { TestEventedMailbox.new }
33
3
  it_behaves_like "a Celluloid Mailbox"
34
4
  end
@@ -1,32 +1,35 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::Future, actor_system: :global do
1
+ RSpec.describe Celluloid::Future, actor_system: :global do
4
2
  it "creates future objects that can be retrieved later" do
5
3
  future = Celluloid::Future.new { 40 + 2 }
6
- future.value.should == 42
4
+ expect(future.value).to eq(42)
7
5
  end
8
6
 
9
7
  it "passes arguments to future blocks" do
10
8
  future = Celluloid::Future.new(40) { |n| n + 2 }
11
- future.value.should == 42
9
+ expect(future.value).to eq(42)
12
10
  end
13
11
 
14
12
  it "reraises exceptions that occur when the value is retrieved" do
15
13
  class ExampleError < StandardError; end
16
14
 
17
- future = Celluloid::Future.new { raise ExampleError, "oh noes crash!" }
15
+ future = Celluloid::Future.new { fail ExampleError, "oh noes crash!" }
18
16
  expect { future.value }.to raise_exception(ExampleError)
19
17
  end
20
18
 
21
19
  it "knows if it's got a value yet" do
22
- future = Celluloid::Future.new { sleep Celluloid::TIMER_QUANTUM * 5 }
23
- future.should_not be_ready
24
- sleep Celluloid::TIMER_QUANTUM * 6
25
- future.should be_ready
20
+ queue = Queue.new
21
+ future = Celluloid::Future.new { queue.pop }
22
+
23
+ expect(future).not_to be_ready
24
+ queue << nil # let it continue
25
+
26
+ Specs.sleep_and_wait_until { future.ready? }
27
+
28
+ expect(future).to be_ready
26
29
  end
27
30
 
28
- it "raises TimeoutError when the future times out" do
31
+ it "raises TaskTimeout when the future times out" do
29
32
  future = Celluloid::Future.new { sleep 2 }
30
- expect { future.value(1) }.to raise_exception(Celluloid::TimeoutError)
33
+ expect { future.value(1) }.to raise_exception(Celluloid::TaskTimeout)
31
34
  end
32
35
  end
File without changes
@@ -0,0 +1,8 @@
1
+ # set logger early on
2
+ require "celluloid/internals/logger"
3
+
4
+ if Celluloid.group_class == Celluloid::Group::Pool
5
+ RSpec.describe Celluloid::Group::Pool do
6
+ it_behaves_like "a Celluloid Group"
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ # set logger early on
2
+ require "celluloid/internals/logger"
3
+
4
+ if Celluloid.group_class == Celluloid::Group::Spawner
5
+ RSpec.describe Celluloid::Group::Spawner do
6
+ it_behaves_like "a Celluloid Group"
7
+
8
+ it "does not leak finished threads" do
9
+ queue = Queue.new
10
+ th = subject.get { queue.pop }
11
+ expect do
12
+ queue << nil
13
+ th.join
14
+ end.to change { subject.group.length }.by(-1)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ RSpec.describe Celluloid::Mailbox::Evented do
2
+ subject { TestEventedMailbox.new }
3
+ it_behaves_like "a Celluloid Mailbox"
4
+
5
+ # NOTE: this example seems too exotic to "have to" succeed on RBX, though I
6
+ # don't know why it hangs on subject.receive and the timeout never occurs
7
+ #
8
+ # Other than
9
+ #
10
+ # Links:
11
+ # https://github.com/celluloid/celluloid-io/pull/98
12
+ # https://github.com/celluloid/celluloid-io/issues/56
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)
23
+
24
+ expect(Time.now - started_at).to be_within(Specs::TIMER_QUANTUM).of timeout_interval
25
+ end
26
+ end
27
+
28
+ it "discard messages when reactor wakeup fails" do
29
+ expect(Celluloid::Internals::Logger).to receive(:crash).with('reactor crashed', RuntimeError)
30
+ expect(Celluloid.logger).to receive(:debug).with("Discarded message (mailbox is dead): first")
31
+
32
+ bad_reactor = Class.new do
33
+ def wakeup
34
+ fail
35
+ end
36
+ end
37
+ mailbox = Celluloid::Mailbox::Evented.new(bad_reactor)
38
+ mailbox << :first
39
+ end
40
+ end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
- describe Celluloid::Mailbox do
1
+ RSpec.describe Celluloid::Mailbox do
4
2
  it_behaves_like "a Celluloid Mailbox"
5
3
  end
@@ -0,0 +1,73 @@
1
+ require "weakref"
2
+
3
+ RSpec.describe "Leaks", actor_system: :global, leaktest: true,
4
+ skip: !ENV["CELLULOID_LEAKTEST"] && "leak test disabled" do
5
+ class LeakActor
6
+ include Celluloid
7
+
8
+ def initialize(arg)
9
+ @arg = arg
10
+ end
11
+
12
+ def call(_arg)
13
+ []
14
+ end
15
+
16
+ def terminate
17
+ end
18
+ end
19
+
20
+ def wait_for_release(weak, _what, count=1000)
21
+ trash = []
22
+ count.times do |step|
23
+ GC.start
24
+ return true unless weak.weakref_alive?
25
+ trash << "*" * step
26
+ end
27
+
28
+ false
29
+ end
30
+
31
+ def do_actor(what)
32
+ actor = LeakActor.new what
33
+ weak = yield actor
34
+ actor.terminate
35
+ actor = nil
36
+ weak
37
+ end
38
+
39
+ def actor_life(what, &block)
40
+ GC.start
41
+ weak = do_actor what, &block
42
+ expect(wait_for_release(weak, what)).to be_truthy
43
+ end
44
+
45
+ context "celluloid actor" do
46
+ it "is properly destroyed upon termination" do
47
+ actor_life("actor") do |actor|
48
+ WeakRef.new actor
49
+ end
50
+ end
51
+ end
52
+
53
+ context "celluloid actor call" do
54
+ it "does not hold a reference its arguments on completion" do
55
+ actor_life("call-arg") do |actor|
56
+ arg = []
57
+ actor.call arg
58
+ weak = WeakRef.new arg
59
+ arg = nil
60
+ weak
61
+ end
62
+ end
63
+
64
+ it "does not hold a reference to the return value" do
65
+ actor_life("call-result") do |actor|
66
+ result = actor.call nil
67
+ weak = WeakRef.new result
68
+ result = nil
69
+ weak
70
+ end
71
+ end
72
+ end
73
+ 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,5 @@
1
+ RSpec.describe Celluloid::Task::Fibered, actor_system: :within do
2
+ if Celluloid.task_class == Celluloid::Task::Fibered
3
+ it_behaves_like "a Celluloid Task"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ RSpec.describe Celluloid::Task::Threaded, actor_system: :within do
2
+ if Celluloid.task_class == Celluloid::Task::Threaded
3
+ it_behaves_like "a Celluloid Task"
4
+ end
5
+ end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  class EveryActor
4
2
  include Celluloid
5
3
 
@@ -7,39 +5,39 @@ class EveryActor
7
5
  @trace = []
8
6
  @times = []
9
7
  @start = Time.now
10
-
8
+
11
9
  every(1) { log(1) }
12
10
  every(2) { log(2) }
13
11
  every(1) { log(11) }
14
12
  every(2) { log(22) }
15
13
  end
16
-
14
+
17
15
  def log(t)
18
16
  @trace << t
19
-
17
+
20
18
  offset = Time.now - @start
21
19
  @times << offset
22
-
20
+
23
21
  # puts "log(#{t}) @ #{offset}"
24
22
  end
25
-
26
- attr :trace
27
- attr :times
23
+
24
+ attr_reader :trace
25
+ attr_reader :times
28
26
  end
29
27
 
30
- describe Celluloid::Actor do
28
+ RSpec.describe "Celluloid::Actor timers" do
31
29
  it "run every(t) task several times" do
32
30
  Celluloid.boot
33
-
31
+
34
32
  every_actor = EveryActor.new
35
-
33
+
36
34
  sleep 5.5
37
-
38
- times = every_actor.times
35
+
36
+ every_actor.times
39
37
  trace = every_actor.trace
40
-
38
+
41
39
  Celluloid.shutdown
42
-
40
+
43
41
  expect(trace.count(1)).to be == 5
44
42
  expect(trace.count(11)).to be == 5
45
43
  expect(trace.count(2)).to be == 2
@@ -0,0 +1,72 @@
1
+ RSpec.describe "Deprecated Celluloid::ActorSystem" do
2
+ subject { Celluloid::ActorSystem.new }
3
+
4
+ class DeprecatedTestActor
5
+ include Celluloid
6
+ end
7
+
8
+ it "supports non-global ActorSystem" do
9
+ subject.within do
10
+ expect(Celluloid.actor_system).to eq(subject)
11
+ end
12
+ end
13
+
14
+ it "starts default actors" do
15
+ subject.start
16
+ expect(subject.registered).to eq(Celluloid::ActorSystem::ROOT_SERVICES.map { |r| r[:as] })
17
+ subject.shutdown
18
+ end
19
+
20
+ it "support getting threads" do
21
+ subject.start
22
+ queue = Queue.new
23
+ thread = subject.get_thread do
24
+ expect(Celluloid.actor_system).to eq(subject)
25
+ queue << nil
26
+ end
27
+ queue.pop
28
+ subject.shutdown
29
+ end
30
+
31
+ it "allows a stack dump" do
32
+ expect(subject.stack_dump).to be_a(Celluloid::StackDump)
33
+ end
34
+
35
+ it "returns named actors" do
36
+ subject.start
37
+
38
+ subject.within do
39
+ DeprecatedTestActor.supervise_as :test
40
+ end
41
+
42
+ expect(subject.registered).to include(:test)
43
+ subject.shutdown
44
+ end
45
+
46
+ it "returns running actors" do
47
+ expect(subject.running).to be_empty
48
+
49
+ first = subject.within do
50
+ DeprecatedTestActor.new
51
+ end
52
+
53
+ second = subject.within do
54
+ DeprecatedTestActor.new
55
+ end
56
+
57
+ expect(subject.running).to eq([first, second])
58
+ subject.shutdown
59
+ end
60
+
61
+ it "shuts down" do
62
+ subject.shutdown
63
+
64
+ expect { subject.get_thread }
65
+ .to raise_error(Celluloid::NotActive)
66
+ end
67
+
68
+ it "warns nicely when no actor system is started" do
69
+ expect { DeprecatedTestActor.new }
70
+ .to raise_error("Celluloid is not yet started; use Celluloid.boot")
71
+ end
72
+ end unless $CELLULOID_BACKPORTED == false
@@ -0,0 +1,52 @@
1
+ RSpec.describe "Deprecated Blocks", actor_system: :global do
2
+ class DeprecatedBlockActor
3
+ include Celluloid
4
+
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+ attr_reader :name
9
+
10
+ def ask_for_something(other)
11
+ sender_actor = current_actor
12
+ $data << [:outside, @name, current_actor.name]
13
+ other.do_something_and_callback do |value|
14
+ $data << [:yielded, @name, current_actor.name]
15
+ $data << receive_result(:self)
16
+ $data << current_actor.receive_result(:current_actor)
17
+ $data << sender_actor.receive_result(:sender)
18
+ "somevalue"
19
+ end
20
+ end
21
+
22
+ def do_something_and_callback
23
+ $data << [:something, @name, current_actor.name]
24
+ $data << yield(:foo)
25
+ end
26
+
27
+ def receive_result(result)
28
+ [result, @name, current_actor.name]
29
+ end
30
+ end
31
+
32
+ it "works" do
33
+ $data = []
34
+
35
+ a1 = DeprecatedBlockActor.new("one")
36
+ a2 = DeprecatedBlockActor.new("two")
37
+
38
+ a1.ask_for_something a2
39
+
40
+ expected = [
41
+ [:outside, "one", "one"],
42
+ [:something, "two", "two"],
43
+ [:yielded, "one", "one"],
44
+ [:self, "one", "one"],
45
+ [:current_actor, "one", "one"],
46
+ [:sender, "one", "one"],
47
+ "somevalue",
48
+ ]
49
+
50
+ expect($data).to eq(expected)
51
+ end
52
+ end unless $CELLULOID_BACKPORTED == false
@@ -0,0 +1,39 @@
1
+ RSpec.describe "Deprecated Celluloid::SyncCall", actor_system: :global do
2
+ subject { Celluloid::SyncCall.new }
3
+
4
+ let(:actor) { DeprecatedCallExampleActor.new }
5
+
6
+ context "when obj does not respond to a method" do
7
+ it "raises a NoMethodError" do
8
+ expect do
9
+ actor.the_method_that_wasnt_there
10
+ end.to raise_exception(NoMethodError)
11
+ expect(actor).to be_alive
12
+ end
13
+
14
+ context "when obj raises during inspect" do
15
+ it "should emulate obj.inspect" do
16
+ expect(actor).to_not receive(:inspect)
17
+ expect { actor.no_such_method }.to raise_exception(
18
+ NoMethodError,
19
+ /undefined method `no_such_method' for #\<DeprecatedCallExampleActor:0x[a-f0-9]+>/,
20
+ )
21
+ end
22
+ end
23
+ end
24
+
25
+ it "aborts with ArgumentError when a method is called with too many arguments" do
26
+ expect do
27
+ actor.actual_method("with too many arguments")
28
+ end.to raise_exception(ArgumentError)
29
+
30
+ expect(actor).to be_alive
31
+ end
32
+
33
+ it "preserves call chains across synchronous calls" do
34
+ actor2 = DeprecatedCallExampleActor.new(actor)
35
+
36
+ uuid, next_actor_uuid = actor2.chained_call_ids
37
+ expect(uuid).to eq next_actor_uuid
38
+ end
39
+ end unless $CELLULOID_BACKPORTED == false