celluloid 0.15.2 → 0.16.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +20 -0
  3. data/README.md +25 -2
  4. data/lib/celluloid/actor.rb +88 -147
  5. data/lib/celluloid/actor_system.rb +107 -0
  6. data/lib/celluloid/call_chain.rb +1 -1
  7. data/lib/celluloid/calls.rb +16 -16
  8. data/lib/celluloid/cell.rb +89 -0
  9. data/lib/celluloid/condition.rb +25 -8
  10. data/lib/celluloid/cpu_counter.rb +28 -18
  11. data/lib/celluloid/evented_mailbox.rb +10 -16
  12. data/lib/celluloid/exceptions.rb +23 -0
  13. data/lib/celluloid/future.rb +1 -1
  14. data/lib/celluloid/handlers.rb +41 -0
  15. data/lib/celluloid/internal_pool.rb +49 -40
  16. data/lib/celluloid/logger.rb +30 -0
  17. data/lib/celluloid/logging/incident_logger.rb +1 -1
  18. data/lib/celluloid/mailbox.rb +35 -31
  19. data/lib/celluloid/method.rb +8 -0
  20. data/lib/celluloid/pool_manager.rb +19 -2
  21. data/lib/celluloid/probe.rb +73 -0
  22. data/lib/celluloid/properties.rb +2 -2
  23. data/lib/celluloid/proxies/actor_proxy.rb +9 -41
  24. data/lib/celluloid/proxies/cell_proxy.rb +68 -0
  25. data/lib/celluloid/proxies/sync_proxy.rb +1 -1
  26. data/lib/celluloid/receivers.rb +5 -13
  27. data/lib/celluloid/registry.rb +1 -8
  28. data/{spec/support → lib/celluloid/rspec}/actor_examples.rb +58 -15
  29. data/{spec/support → lib/celluloid/rspec}/mailbox_examples.rb +9 -3
  30. data/{spec/support → lib/celluloid/rspec}/task_examples.rb +2 -0
  31. data/lib/celluloid/rspec.rb +4 -3
  32. data/lib/celluloid/stack_dump.rb +34 -11
  33. data/lib/celluloid/supervision_group.rb +26 -14
  34. data/lib/celluloid/tasks/task_fiber.rb +6 -0
  35. data/lib/celluloid/tasks/task_thread.rb +2 -1
  36. data/lib/celluloid/tasks.rb +28 -9
  37. data/lib/celluloid/thread_handle.rb +2 -2
  38. data/lib/celluloid.rb +68 -73
  39. data/spec/celluloid/actor_spec.rb +1 -1
  40. data/spec/celluloid/actor_system_spec.rb +69 -0
  41. data/spec/celluloid/block_spec.rb +1 -1
  42. data/spec/celluloid/calls_spec.rb +1 -1
  43. data/spec/celluloid/condition_spec.rb +14 -3
  44. data/spec/celluloid/cpu_counter_spec.rb +82 -0
  45. data/spec/celluloid/fsm_spec.rb +1 -1
  46. data/spec/celluloid/future_spec.rb +1 -1
  47. data/spec/celluloid/notifications_spec.rb +1 -1
  48. data/spec/celluloid/pool_spec.rb +34 -1
  49. data/spec/celluloid/probe_spec.rb +121 -0
  50. data/spec/celluloid/registry_spec.rb +6 -6
  51. data/spec/celluloid/stack_dump_spec.rb +37 -8
  52. data/spec/celluloid/supervision_group_spec.rb +7 -1
  53. data/spec/celluloid/supervisor_spec.rb +12 -1
  54. data/spec/celluloid/tasks/task_fiber_spec.rb +1 -1
  55. data/spec/celluloid/tasks/task_thread_spec.rb +1 -1
  56. data/spec/celluloid/thread_handle_spec.rb +7 -3
  57. data/spec/celluloid/timer_spec.rb +48 -0
  58. data/spec/spec_helper.rb +20 -7
  59. metadata +51 -26
  60. /data/{spec/support → lib/celluloid/rspec}/example_actor_class.rb +0 -0
@@ -5,6 +5,7 @@ module Celluloid
5
5
  trap_exit :restart_actor
6
6
 
7
7
  class << self
8
+
8
9
  # Actors or sub-applications to be supervised
9
10
  def blocks
10
11
  @blocks ||= []
@@ -55,10 +56,12 @@ module Celluloid
55
56
  end
56
57
  end
57
58
 
59
+ finalizer :finalize
60
+
58
61
  # Start the group
59
62
  def initialize(registry = nil)
60
63
  @members = []
61
- @registry = registry || Registry.root
64
+ @registry = registry || Celluloid.actor_system.registry
62
65
 
63
66
  yield current_actor if block_given?
64
67
  end
@@ -81,18 +84,15 @@ module Celluloid
81
84
  def add(klass, options)
82
85
  member = Member.new(@registry, klass, options)
83
86
  @members << member
84
- member
87
+ member.actor
85
88
  end
86
89
 
87
90
  def actors
88
91
  @members.map(&:actor)
89
92
  end
90
93
 
91
- finalizer :finalize
92
-
93
- # Terminate the group
94
- def finalize
95
- @members.reverse_each(&:terminate)
94
+ def [](actor_name)
95
+ @registry[actor_name]
96
96
  end
97
97
 
98
98
  # Restart a crashed actor
@@ -102,7 +102,12 @@ module Celluloid
102
102
  end
103
103
  raise "a group member went missing. This shouldn't be!" unless member
104
104
 
105
- member.restart(reason)
105
+ if reason
106
+ member.restart
107
+ else
108
+ member.cleanup
109
+ @members.delete(member)
110
+ end
106
111
  end
107
112
 
108
113
  # A member of the group
@@ -137,21 +142,28 @@ module Celluloid
137
142
  @registry[@name] = @actor if @name
138
143
  end
139
144
 
140
- def restart(reason)
145
+ def restart
141
146
  @actor = nil
142
- @registry.delete(@name) if @name
143
-
144
- # Ignore supervisors that shut down cleanly
145
- return unless reason
147
+ cleanup
146
148
 
147
149
  start
148
150
  end
149
151
 
150
152
  def terminate
151
- @registry.delete(@name) if @name
153
+ cleanup
152
154
  @actor.terminate if @actor
153
155
  rescue DeadActorError
154
156
  end
157
+
158
+ def cleanup
159
+ @registry.delete(@name) if @name
160
+ end
161
+ end
162
+
163
+ private
164
+
165
+ def finalize
166
+ @members.reverse_each(&:terminate) if @members
155
167
  end
156
168
  end
157
169
  end
@@ -6,10 +6,12 @@ module Celluloid
6
6
 
7
7
  def create
8
8
  queue = Thread.current[:celluloid_queue]
9
+ actor_system = Thread.current[:celluloid_actor_system]
9
10
  @fiber = Fiber.new do
10
11
  # FIXME: cannot use the writer as specs run inside normal Threads
11
12
  Thread.current[:celluloid_role] = :actor
12
13
  Thread.current[:celluloid_queue] = queue
14
+ Thread.current[:celluloid_actor_system] = actor_system
13
15
  yield
14
16
  end
15
17
  end
@@ -33,5 +35,9 @@ module Celluloid
33
35
  rescue FiberError
34
36
  # If we're getting this the task should already be dead
35
37
  end
38
+
39
+ def backtrace
40
+ ["#{self.class} backtrace unavailable. Please try `Celluloid.task_class = Celluloid::TaskThread` if you need backtraces here."]
41
+ end
36
42
  end
37
43
  end
@@ -12,7 +12,8 @@ module Celluloid
12
12
  end
13
13
 
14
14
  def create
15
- @thread = Celluloid::ThreadHandle.new(:task) do
15
+ # TODO: move this to ActorSystem#get_thread (ThreadHandle inside InternalPool)
16
+ @thread = ThreadHandle.new(Thread.current[:celluloid_actor_system], :task) do
16
17
  begin
17
18
  ex = @resume_queue.pop
18
19
  raise ex if ex.is_a?(Task::TerminatedError)
@@ -48,6 +48,8 @@ module Celluloid
48
48
  @status = :running
49
49
  actor.setup_thread
50
50
 
51
+ name_current_thread thread_metadata
52
+
51
53
  Thread.current[:celluloid_task] = self
52
54
  CallChain.current_id = @chain_id
53
55
 
@@ -56,6 +58,7 @@ module Celluloid
56
58
  rescue Task::TerminatedError
57
59
  # Task was explicitly terminated
58
60
  ensure
61
+ name_current_thread nil
59
62
  @status = :dead
60
63
  actor.tasks.delete self
61
64
  end
@@ -74,14 +77,9 @@ module Celluloid
74
77
  @status = status
75
78
 
76
79
  if $CELLULOID_DEBUG && @dangerous_suspend
77
- warning = "Dangerously suspending task: "
78
- warning << [
79
- "type=#{@type.inspect}",
80
- "meta=#{@meta.inspect}",
81
- "status=#{@status.inspect}"
82
- ].join(", ")
83
-
84
- Logger.warn [warning, *caller[2..8]].join("\n\t")
80
+ Logger.with_backtrace(caller[2...8]) do |logger|
81
+ logger.warn "Dangerously suspending task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}"
82
+ end
85
83
  end
86
84
 
87
85
  value = signal
@@ -118,7 +116,9 @@ module Celluloid
118
116
  raise "Cannot terminate an exclusive task" if exclusive?
119
117
 
120
118
  if running?
121
- Celluloid.logger.warn "Terminating task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}"
119
+ Logger.with_backtrace(backtrace) do |logger|
120
+ logger.warn "Terminating task: type=#{@type.inspect}, meta=#{@meta.inspect}, status=#{@status.inspect}"
121
+ end
122
122
  exception = Task::TerminatedError.new("task was terminated")
123
123
  exception.set_backtrace(caller)
124
124
  resume exception
@@ -150,6 +150,25 @@ module Celluloid
150
150
  raise message if $CELLULOID_DEBUG
151
151
  end
152
152
  end
153
+
154
+ private
155
+
156
+ def name_current_thread(new_name)
157
+ return unless RUBY_PLATFORM == "java"
158
+ if new_name.nil?
159
+ new_name = Thread.current[:celluloid_original_thread_name]
160
+ Thread.current[:celluloid_original_thread_name] = nil
161
+ else
162
+ Thread.current[:celluloid_original_thread_name] = Thread.current.to_java.getNativeThread.get_name
163
+ end
164
+ Thread.current.to_java.getNativeThread.set_name(new_name)
165
+ end
166
+
167
+ def thread_metadata
168
+ method = @meta && @meta[:method_name] || "<no method>"
169
+ klass = Thread.current[:celluloid_actor] && Thread.current[:celluloid_actor].behavior.subject.bare_object.class || "<no actor>"
170
+ format("[Celluloid] %s#%s", klass, method)
171
+ end
153
172
  end
154
173
  end
155
174
 
@@ -3,11 +3,11 @@ module Celluloid
3
3
  # accidentally do things to threads which have been returned to the pool,
4
4
  # such as, say, killing them
5
5
  class ThreadHandle
6
- def initialize(role = nil)
6
+ def initialize(actor_system, role = nil)
7
7
  @mutex = Mutex.new
8
8
  @join = ConditionVariable.new
9
9
 
10
- @thread = Celluloid.internal_pool.get do
10
+ @thread = actor_system.get_thread do
11
11
  Thread.current.role = role
12
12
  begin
13
13
  yield
data/lib/celluloid.rb CHANGED
@@ -3,25 +3,32 @@ require 'thread'
3
3
  require 'timeout'
4
4
  require 'set'
5
5
 
6
- if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
7
- raise "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
8
- end
9
-
10
6
  module Celluloid
11
- VERSION = '0.15.2'
12
- Error = Class.new StandardError
7
+ # Expose all instance methods as singleton methods
8
+ extend self
9
+
10
+ VERSION = '0.16.0'
13
11
 
14
- extend self # expose all instance methods as singleton methods
12
+ # Linking times out after 5 seconds
13
+ LINKING_TIMEOUT = 5
15
14
 
16
15
  # Warning message added to Celluloid objects accessed outside their actors
17
16
  BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT "
18
17
 
19
18
  class << self
20
- attr_accessor :internal_pool # Internal thread pool
19
+ attr_writer :actor_system # Default Actor System
21
20
  attr_accessor :logger # Thread-safe logger class
22
21
  attr_accessor :task_class # Default task type to use
23
22
  attr_accessor :shutdown_timeout # How long actors have to terminate
24
23
 
24
+ def actor_system
25
+ if Thread.current.celluloid?
26
+ Thread.current[:celluloid_actor_system] or raise Error, "actor system not running"
27
+ else
28
+ Thread.current[:celluloid_actor_system] || @actor_system or raise Error, "Celluloid is not yet started; use Celluloid.boot"
29
+ end
30
+ end
31
+
25
32
  def included(klass)
26
33
  klass.send :extend, ClassMethods
27
34
  klass.send :include, InstanceMethods
@@ -29,19 +36,29 @@ module Celluloid
29
36
  klass.send :extend, Properties
30
37
 
31
38
  klass.property :mailbox_class, :default => Celluloid::Mailbox
32
- klass.property :proxy_class, :default => Celluloid::ActorProxy
39
+ klass.property :proxy_class, :default => Celluloid::CellProxy
33
40
  klass.property :task_class, :default => Celluloid.task_class
34
41
  klass.property :mailbox_size
35
42
 
43
+ klass.property :exclusive_actor, :default => false
44
+ klass.property :exclusive_methods, :multi => true
36
45
  klass.property :execute_block_on_receiver,
37
46
  :default => [:after, :every, :receive],
38
47
  :multi => true
39
48
 
40
49
  klass.property :finalizer
41
- klass.property :exit_handler
50
+ klass.property :exit_handler_name
42
51
 
43
52
  klass.send(:define_singleton_method, :trap_exit) do |*args|
44
- exit_handler(*args)
53
+ exit_handler_name(*args)
54
+ end
55
+
56
+ klass.send(:define_singleton_method, :exclusive) do |*args|
57
+ if args.any?
58
+ exclusive_methods(*exclusive_methods, *args)
59
+ else
60
+ exclusive_actor true
61
+ end
45
62
  end
46
63
  end
47
64
 
@@ -69,7 +86,7 @@ module Celluloid
69
86
 
70
87
  # Perform a stack dump of all actors to the given output object
71
88
  def stack_dump(output = STDERR)
72
- Celluloid::StackDump.new.dump(output)
89
+ actor_system.stack_dump.print(output)
73
90
  end
74
91
  alias_method :dump, :stack_dump
75
92
 
@@ -106,18 +123,15 @@ module Celluloid
106
123
  end
107
124
 
108
125
  def init
109
- self.internal_pool = InternalPool.new
126
+ @actor_system = ActorSystem.new
110
127
  end
111
128
 
112
- # Launch default services
113
- # FIXME: We should set up the supervision hierarchy here
114
129
  def start
115
- Celluloid::Notifications::Fanout.supervise_as :notifications_fanout
116
- Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR
130
+ actor_system.start
117
131
  end
118
132
 
119
133
  def running?
120
- internal_pool
134
+ actor_system && actor_system.running?
121
135
  end
122
136
 
123
137
  def register_shutdown
@@ -139,41 +153,7 @@ module Celluloid
139
153
 
140
154
  # Shut down all running actors
141
155
  def shutdown
142
- actors = Actor.all
143
-
144
- Timeout.timeout(shutdown_timeout) do
145
- internal_pool.shutdown
146
-
147
- Logger.debug "Terminating #{actors.size} #{(actors.size > 1) ? 'actors' : 'actor'}..." if actors.size > 0
148
-
149
- # Attempt to shut down the supervision tree, if available
150
- Supervisor.root.terminate if Supervisor.root
151
-
152
- # Actors cannot self-terminate, you must do it for them
153
- actors.each do |actor|
154
- begin
155
- actor.terminate!
156
- rescue DeadActorError
157
- end
158
- end
159
-
160
- actors.each do |actor|
161
- begin
162
- Actor.join(actor)
163
- rescue DeadActorError
164
- end
165
- end
166
- end
167
- rescue Timeout::Error
168
- Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!")
169
- actors.each do |actor|
170
- begin
171
- Actor.kill(actor)
172
- rescue DeadActorError, MailboxDead
173
- end
174
- end
175
- ensure
176
- internal_pool.kill
156
+ actor_system.shutdown
177
157
  end
178
158
 
179
159
  def version
@@ -185,7 +165,7 @@ module Celluloid
185
165
  module ClassMethods
186
166
  # Create a new actor
187
167
  def new(*args, &block)
188
- proxy = Actor.new(allocate, actor_options).proxy
168
+ proxy = Cell.new(allocate, behavior_options, actor_options).proxy
189
169
  proxy._send_(:initialize, *args, &block)
190
170
  proxy
191
171
  end
@@ -195,7 +175,7 @@ module Celluloid
195
175
  def new_link(*args, &block)
196
176
  raise NotActorError, "can't link outside actor context" unless Celluloid.actor?
197
177
 
198
- proxy = Actor.new(allocate, actor_options).proxy
178
+ proxy = Cell.new(allocate, behavior_options, actor_options).proxy
199
179
  Actor.link(proxy)
200
180
  proxy._send_(:initialize, *args, &block)
201
181
  proxy
@@ -233,26 +213,28 @@ module Celluloid
233
213
  Actor.join(new(*args, &block))
234
214
  end
235
215
 
236
- # Mark methods as running exclusively
237
- def exclusive(*methods)
238
- if methods.empty?
239
- @exclusive_methods = :all
240
- elsif !defined?(@exclusive_methods) || @exclusive_methods != :all
241
- @exclusive_methods ||= Set.new
242
- @exclusive_methods.merge methods.map(&:to_sym)
243
- end
216
+ def actor_system
217
+ Celluloid.actor_system
244
218
  end
245
219
 
246
220
  # Configuration options for Actor#new
247
221
  def actor_options
248
222
  {
223
+ :actor_system => actor_system,
249
224
  :mailbox_class => mailbox_class,
250
225
  :mailbox_size => mailbox_size,
251
- :proxy_class => proxy_class,
252
226
  :task_class => task_class,
253
- :exit_handler => exit_handler,
254
- :exclusive_methods => defined?(@exclusive_methods) ? @exclusive_methods : nil,
255
- :receiver_block_executions => execute_block_on_receiver
227
+ :exclusive => exclusive_actor,
228
+ }
229
+ end
230
+
231
+ def behavior_options
232
+ {
233
+ :proxy_class => proxy_class,
234
+ :exclusive_methods => exclusive_methods,
235
+ :exit_handler_name => exit_handler_name,
236
+ :finalizer => finalizer,
237
+ :receiver_block_executions => execute_block_on_receiver,
256
238
  }
257
239
  end
258
240
 
@@ -291,9 +273,10 @@ module Celluloid
291
273
  end
292
274
 
293
275
  # Obtain the name of the current actor
294
- def name
295
- Actor.name
276
+ def registered_name
277
+ Actor.registered_name
296
278
  end
279
+ alias_method :name, :registered_name
297
280
 
298
281
  def inspect
299
282
  return "..." if Celluloid.detect_recursion
@@ -303,7 +286,7 @@ module Celluloid
303
286
  if leaked?
304
287
  str << Celluloid::BARE_OBJECT_WARNING_MESSAGE
305
288
  else
306
- str << "Celluloid::ActorProxy"
289
+ str << "Celluloid::CellProxy"
307
290
  end
308
291
 
309
292
  str << "(#{self.class}:0x#{object_id.to_s(16)})"
@@ -335,7 +318,7 @@ module Celluloid
335
318
 
336
319
  # Terminate this actor
337
320
  def terminate
338
- Thread.current[:celluloid_actor].proxy.terminate!
321
+ Thread.current[:celluloid_actor].behavior_proxy.terminate!
339
322
  end
340
323
 
341
324
  # Send a signal with the given name to all waiting methods
@@ -458,15 +441,21 @@ module Celluloid
458
441
 
459
442
  # Handle async calls within an actor itself
460
443
  def async(meth = nil, *args, &block)
461
- Thread.current[:celluloid_actor].proxy.async meth, *args, &block
444
+ Thread.current[:celluloid_actor].behavior_proxy.async meth, *args, &block
462
445
  end
463
446
 
464
447
  # Handle calls to future within an actor itself
465
448
  def future(meth = nil, *args, &block)
466
- Thread.current[:celluloid_actor].proxy.future meth, *args, &block
449
+ Thread.current[:celluloid_actor].behavior_proxy.future meth, *args, &block
467
450
  end
468
451
  end
469
452
 
453
+ if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
454
+ raise "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
455
+ end
456
+
457
+ require 'celluloid/exceptions'
458
+
470
459
  require 'celluloid/calls'
471
460
  require 'celluloid/call_chain'
472
461
  require 'celluloid/condition'
@@ -482,6 +471,7 @@ require 'celluloid/mailbox'
482
471
  require 'celluloid/evented_mailbox'
483
472
  require 'celluloid/method'
484
473
  require 'celluloid/properties'
474
+ require 'celluloid/handlers'
485
475
  require 'celluloid/receivers'
486
476
  require 'celluloid/registry'
487
477
  require 'celluloid/responses'
@@ -495,13 +485,16 @@ require 'celluloid/uuid'
495
485
 
496
486
  require 'celluloid/proxies/abstract_proxy'
497
487
  require 'celluloid/proxies/sync_proxy'
488
+ require 'celluloid/proxies/cell_proxy'
498
489
  require 'celluloid/proxies/actor_proxy'
499
490
  require 'celluloid/proxies/async_proxy'
500
491
  require 'celluloid/proxies/future_proxy'
501
492
  require 'celluloid/proxies/block_proxy'
502
493
 
503
494
  require 'celluloid/actor'
495
+ require 'celluloid/cell'
504
496
  require 'celluloid/future'
497
+ require 'celluloid/actor_system'
505
498
  require 'celluloid/pool_manager'
506
499
  require 'celluloid/supervision_group'
507
500
  require 'celluloid/supervisor'
@@ -510,6 +503,8 @@ require 'celluloid/logging'
510
503
 
511
504
  require 'celluloid/legacy' unless defined?(CELLULOID_FUTURE)
512
505
 
506
+ $CELLULOID_MONITORING = false
507
+
513
508
  # Configure default systemwide settings
514
509
  Celluloid.task_class = Celluloid::TaskFiber
515
510
  Celluloid.logger = Logger.new(STDERR)
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Celluloid do
3
+ describe Celluloid, actor_system: :global do
4
4
  it_behaves_like "a Celluloid Actor", Celluloid
5
5
  end
@@ -0,0 +1,69 @@
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,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Blocks" do
3
+ describe "Blocks", actor_system: :global do
4
4
  class MyBlockActor
5
5
  include Celluloid
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Celluloid::SyncCall do
3
+ describe Celluloid::SyncCall, actor_system: :global do
4
4
  class CallExampleActor
5
5
  include Celluloid
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Celluloid::Condition do
3
+ describe Celluloid::Condition, actor_system: :global do
4
4
  class ConditionExample
5
5
  include Celluloid
6
6
 
@@ -17,10 +17,10 @@ describe Celluloid::Condition do
17
17
  condition.signal value
18
18
  end
19
19
 
20
- def wait_for_condition
20
+ def wait_for_condition(timeout = nil)
21
21
  @waiting = true
22
22
  begin
23
- value = @condition.wait
23
+ value = @condition.wait(timeout)
24
24
  @signaled_times += 1
25
25
  ensure
26
26
  @waiting = false
@@ -62,4 +62,15 @@ describe Celluloid::Condition do
62
62
  actor.async.signal_condition condition, :value
63
63
  condition.wait.should eq(:value)
64
64
  end
65
+
66
+ it "times out inside normal Threads" do
67
+ condition = Celluloid::Condition.new
68
+ lambda { condition.wait(1) }.
69
+ should raise_error(Celluloid::ConditionError)
70
+ end
71
+
72
+ it "times out inside Tasks" do
73
+ lambda { actor.wait_for_condition(1) }.
74
+ should raise_error(Celluloid::ConditionError)
75
+ end
65
76
  end