celluloid 0.17.0 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of celluloid might be problematic. Click here for more details.

Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +10 -2
  3. data/LICENSE.txt +1 -1
  4. data/README.md +26 -14
  5. data/culture/gems/dependencies.yml +8 -2
  6. data/examples/stack.rb +47 -0
  7. data/lib/celluloid.rb +9 -6
  8. data/lib/celluloid/actor.rb +7 -32
  9. data/lib/celluloid/actor/manager.rb +7 -0
  10. data/lib/celluloid/actor/system.rb +163 -0
  11. data/lib/celluloid/call/sync.rb +1 -1
  12. data/lib/celluloid/calls.rb +3 -3
  13. data/lib/celluloid/cell.rb +1 -1
  14. data/lib/celluloid/condition.rb +3 -4
  15. data/lib/celluloid/debug.rb +1 -0
  16. data/lib/celluloid/deprecate.rb +3 -0
  17. data/lib/celluloid/exceptions.rb +20 -15
  18. data/lib/celluloid/future.rb +40 -3
  19. data/lib/celluloid/group.rb +5 -9
  20. data/lib/celluloid/group/pool.rb +1 -1
  21. data/lib/celluloid/group/spawner.rb +1 -2
  22. data/lib/celluloid/mailbox.rb +2 -2
  23. data/lib/celluloid/managed.rb +3 -0
  24. data/lib/celluloid/notices.rb +1 -1
  25. data/lib/celluloid/proxies.rb +7 -8
  26. data/lib/celluloid/proxy/abstract.rb +16 -21
  27. data/lib/celluloid/proxy/actor.rb +33 -37
  28. data/lib/celluloid/proxy/async.rb +24 -29
  29. data/lib/celluloid/proxy/block.rb +20 -24
  30. data/lib/celluloid/proxy/cell.rb +58 -62
  31. data/lib/celluloid/proxy/future.rb +33 -37
  32. data/lib/celluloid/proxy/sync.rb +31 -35
  33. data/lib/celluloid/system_events.rb +53 -1
  34. data/lib/celluloid/task.rb +13 -21
  35. data/lib/celluloid/task/fibered.rb +1 -1
  36. data/lib/celluloid/task/threaded.rb +2 -2
  37. data/lib/celluloid/version.rb +1 -1
  38. data/spec/celluloid/{group → actor}/manager_spec.rb +0 -0
  39. data/spec/celluloid/{actor_system_spec.rb → actor/system_spec.rb} +4 -4
  40. data/spec/celluloid/block_spec.rb +64 -3
  41. data/spec/celluloid/condition_spec.rb +6 -0
  42. data/spec/celluloid/future_spec.rb +2 -2
  43. data/spec/deprecate/actor_system_spec.rb +1 -1
  44. data/spec/deprecate/future_spec.rb +2 -2
  45. data/spec/shared/actor_examples.rb +20 -4
  46. data/spec/shared/group_examples.rb +1 -1
  47. data/spec/shared/mailbox_examples.rb +1 -1
  48. data/spec/spec_helper.rb +3 -3
  49. metadata +110 -76
  50. data/lib/celluloid/actor_system.rb +0 -160
  51. data/lib/celluloid/group/manager.rb +0 -27
@@ -1,36 +1,31 @@
1
- module Celluloid
2
- module Proxy
3
- # A proxy which sends asynchronous calls to an actor
4
- class Async < Abstract
5
- attr_reader :mailbox
1
+ # A proxy which sends asynchronous calls to an actor
2
+ class Celluloid::Proxy::Async < Celluloid::Proxy::Abstract
3
+ attr_reader :mailbox
6
4
 
7
- # Used for reflecting on proxy objects themselves
8
- def __class__
9
- Proxy::Async
10
- end
11
-
12
- def initialize(mailbox, klass)
13
- @mailbox = mailbox
14
- @klass = klass
15
- end
16
-
17
- def inspect
18
- "#<Celluloid::Proxy::Async(#{@klass})>"
19
- end
5
+ # Used for reflecting on proxy objects themselves
6
+ def __class__
7
+ ::Celluloid::Proxy::Async
8
+ end
20
9
 
21
- def method_missing(meth, *args, &block)
22
- if @mailbox == ::Thread.current[:celluloid_mailbox]
23
- args.unshift meth
24
- meth = :__send__
25
- end
10
+ def initialize(mailbox, klass)
11
+ @mailbox = mailbox
12
+ @klass = klass
13
+ end
26
14
 
27
- if block_given?
28
- # FIXME: nicer exception
29
- fail "Cannot use blocks with async yet"
30
- end
15
+ def inspect
16
+ "#<Celluloid::Proxy::Async(#{@klass})>"
17
+ end
31
18
 
32
- @mailbox << Call::Async.new(meth, args, block)
33
- end
19
+ def method_missing(meth, *args, &block)
20
+ if @mailbox == ::Thread.current[:celluloid_mailbox]
21
+ args.unshift meth
22
+ meth = :__send__
23
+ end
24
+ if block_given?
25
+ # FIXME: nicer exception
26
+ fail "Cannot use blocks with async yet"
34
27
  end
28
+ @mailbox << ::Celluloid::Call::Async.new(meth, args, block)
29
+ self
35
30
  end
36
31
  end
@@ -1,31 +1,27 @@
1
- module Celluloid
2
- module Proxy
3
- class Block
4
- def initialize(call, mailbox, block)
5
- @call = call
6
- @mailbox = mailbox
7
- @block = block
8
- @execution = :sender
9
- end
10
- attr_writer :execution
11
- attr_reader :call, :block
1
+ class Celluloid::Proxy::Block
2
+ attr_writer :execution
3
+ attr_reader :call, :block
4
+ def initialize(mailbox, call, block)
5
+ @mailbox = mailbox
6
+ @call = call
7
+ @block = block
8
+ @execution = :sender
9
+ end
12
10
 
13
- def to_proc
14
- if @execution == :sender
15
- lambda do |*values|
16
- if task = Thread.current[:celluloid_task]
17
- @mailbox << Call::Block.new(self, Celluloid::Actor.current.mailbox, values)
18
- # TODO: if respond fails, the Task will never be resumed
19
- task.suspend(:invokeblock)
20
- else
21
- # FIXME: better exception
22
- fail "No task to suspend"
23
- end
24
- end
11
+ def to_proc
12
+ if @execution == :sender
13
+ lambda do |*values|
14
+ if task = Thread.current[:celluloid_task]
15
+ @mailbox << ::Celluloid::Call::Block.new(self, ::Celluloid::Actor.current.mailbox, values)
16
+ # TODO: if respond fails, the Task will never be resumed
17
+ task.suspend(:invokeblock)
25
18
  else
26
- @block
19
+ # FIXME: better exception
20
+ fail "No task to suspend"
27
21
  end
28
22
  end
23
+ else
24
+ @block
29
25
  end
30
26
  end
31
27
  end
@@ -1,76 +1,72 @@
1
- module Celluloid
2
- module Proxy
3
- # A proxy object returned from Celluloid::Actor.new/new_link which converts
4
- # the normal Ruby method protocol into an inter-actor message protocol
5
- class Cell < Sync
6
- # Used for reflecting on proxy objects themselves
7
- def __class__
8
- Proxy::Cell
9
- end
1
+ # A proxy object returned from Celluloid::Actor.new/new_link which converts
2
+ # the normal Ruby method protocol into an inter-actor message protocol
3
+ class Celluloid::Proxy::Cell < Celluloid::Proxy::Sync
4
+ # Used for reflecting on proxy objects themselves
5
+ def __class__
6
+ ::Celluloid::Proxy::Cell
7
+ end
10
8
 
11
- def initialize(actor_proxy, mailbox, klass)
12
- super(mailbox, klass)
13
- @actor_proxy = actor_proxy
14
- @sync_proxy = Sync.new(mailbox, klass)
15
- @async_proxy = Async.new(mailbox, klass)
16
- @future_proxy = Future.new(mailbox, klass)
17
- end
9
+ def initialize(mailbox, actor_proxy, klass)
10
+ super(mailbox, klass)
11
+ @actor_proxy = actor_proxy
12
+ @sync_proxy = ::Celluloid::Proxy::Sync.new(mailbox, klass)
13
+ @async_proxy = ::Celluloid::Proxy::Async.new(mailbox, klass)
14
+ @future_proxy = ::Celluloid::Proxy::Future.new(mailbox, klass)
15
+ end
18
16
 
19
- def _send_(meth, *args, &block)
20
- method_missing :__send__, meth, *args, &block
21
- end
17
+ def _send_(meth, *args, &block)
18
+ method_missing :__send__, meth, *args, &block
19
+ end
22
20
 
23
- def inspect
24
- method_missing :inspect
25
- rescue DeadActorError
26
- "#<Celluloid::Proxy::Cell(#{@klass}) dead>"
27
- end
21
+ def inspect
22
+ method_missing :inspect
23
+ rescue ::Celluloid::DeadActorError
24
+ "#<::Celluloid::Proxy::Cell(#{@klass}) dead>"
25
+ end
28
26
 
29
- def method(name)
30
- Internals::Method.new(self, name)
31
- end
27
+ def method(name)
28
+ ::Celluloid::Internals::Method.new(self, name)
29
+ end
32
30
 
33
- alias_method :sync, :method_missing
31
+ alias_method :sync, :method_missing
34
32
 
35
- # Obtain an async proxy or explicitly invoke a named async method
36
- def async(method_name = nil, *args, &block)
37
- if method_name
38
- @async_proxy.method_missing method_name, *args, &block
39
- else
40
- @async_proxy
41
- end
42
- end
33
+ # Obtain an async proxy or explicitly invoke a named async method
34
+ def async(method_name = nil, *args, &block)
35
+ if method_name
36
+ @async_proxy.method_missing method_name, *args, &block
37
+ else
38
+ @async_proxy
39
+ end
40
+ end
43
41
 
44
- # Obtain a future proxy or explicitly invoke a named future method
45
- def future(method_name = nil, *args, &block)
46
- if method_name
47
- @future_proxy.method_missing method_name, *args, &block
48
- else
49
- @future_proxy
50
- end
51
- end
42
+ # Obtain a future proxy or explicitly invoke a named future method
43
+ def future(method_name = nil, *args, &block)
44
+ if method_name
45
+ @future_proxy.method_missing method_name, *args, &block
46
+ else
47
+ @future_proxy
48
+ end
49
+ end
52
50
 
53
- def alive?
54
- @actor_proxy.alive?
55
- end
51
+ def alive?
52
+ @actor_proxy.alive?
53
+ end
56
54
 
57
- def dead?
58
- @actor_proxy.dead?
59
- end
55
+ def dead?
56
+ @actor_proxy.dead?
57
+ end
60
58
 
61
- def thread
62
- @actor_proxy.thread
63
- end
59
+ def thread
60
+ @actor_proxy.thread
61
+ end
64
62
 
65
- # Terminate the associated actor
66
- def terminate
67
- @actor_proxy.terminate
68
- end
63
+ # Terminate the associated actor
64
+ def terminate
65
+ @actor_proxy.terminate
66
+ end
69
67
 
70
- # Terminate the associated actor asynchronously
71
- def terminate!
72
- @actor_proxy.terminate!
73
- end
74
- end
68
+ # Terminate the associated actor asynchronously
69
+ def terminate!
70
+ @actor_proxy.terminate!
75
71
  end
76
72
  end
@@ -1,40 +1,36 @@
1
- module Celluloid
2
- module Proxy
3
- # A proxy which creates future calls to an actor
4
- class Future < Abstract
5
- attr_reader :mailbox
6
-
7
- # Used for reflecting on proxy objects themselves
8
- def __class__
9
- Proxy::Future
10
- end
11
-
12
- def initialize(mailbox, klass)
13
- @mailbox = mailbox
14
- @klass = klass
15
- end
16
-
17
- def inspect
18
- "#<Celluloid::Proxy::Future(#{@klass})>"
19
- end
20
-
21
- def method_missing(meth, *args, &block)
22
- unless @mailbox.alive?
23
- fail DeadActorError, "attempted to call a dead actor"
24
- end
25
-
26
- if block_given?
27
- # FIXME: nicer exception
28
- fail "Cannot use blocks with futures yet"
29
- end
30
-
31
- future = ::Celluloid::Future.new
32
- call = Call::Sync.new(future, meth, args, block)
33
-
34
- @mailbox << call
35
-
36
- future
37
- end
1
+ # A proxy which creates future calls to an actor
2
+ class Celluloid::Proxy::Future < Celluloid::Proxy::Abstract
3
+ attr_reader :mailbox
4
+
5
+ # Used for reflecting on proxy objects themselves
6
+ def __class__
7
+ ::Celluloid::Proxy::Future
8
+ end
9
+
10
+ def initialize(mailbox, klass)
11
+ @mailbox = mailbox
12
+ @klass = klass
13
+ end
14
+
15
+ def inspect
16
+ "#<Celluloid::Proxy::Future(#{@klass})>"
17
+ end
18
+
19
+ def method_missing(meth, *args, &block)
20
+ unless @mailbox.alive?
21
+ fail ::Celluloid::DeadActorError, "attempted to call a dead actor"
22
+ end
23
+
24
+ if block_given?
25
+ # FIXME: nicer exception
26
+ fail "Cannot use blocks with futures yet"
38
27
  end
28
+
29
+ future = ::Celluloid::Future.new
30
+ call = ::Celluloid::Call::Sync.new(future, meth, args, block)
31
+
32
+ @mailbox << call
33
+
34
+ future
39
35
  end
40
36
  end
@@ -1,44 +1,40 @@
1
- module Celluloid
2
- module Proxy
3
- # A proxy which sends synchronous calls to an actor
4
- class Sync < Abstract
5
- attr_reader :mailbox
1
+ # A proxy which sends synchronous calls to an actor
2
+ class Celluloid::Proxy::Sync < Celluloid::Proxy::Abstract
3
+ attr_reader :mailbox
6
4
 
7
- # Used for reflecting on proxy objects themselves
8
- def __class__
9
- Proxy::Sync
10
- end
11
-
12
- def initialize(mailbox, klass)
13
- @mailbox = mailbox
14
- @klass = klass
15
- end
5
+ # Used for reflecting on proxy objects themselves
6
+ def __class__
7
+ ::Celluloid::Proxy::Sync
8
+ end
16
9
 
17
- def inspect
18
- "#<Celluloid::Proxy::Sync(#{@klass})>"
19
- end
10
+ def initialize(mailbox, klass)
11
+ @mailbox = mailbox
12
+ @klass = klass
13
+ end
20
14
 
21
- def respond_to?(meth, include_private = false)
22
- __class__.instance_methods.include?(meth) || method_missing(:respond_to?, meth, include_private)
23
- end
15
+ def inspect
16
+ "#<Celluloid::Proxy::Sync(#{@klass})>"
17
+ end
24
18
 
25
- def method_missing(meth, *args, &block)
26
- unless @mailbox.alive?
27
- fail DeadActorError, "attempted to call a dead actor"
28
- end
19
+ def respond_to?(meth, include_private = false)
20
+ __class__.instance_methods.include?(meth) || method_missing(:respond_to?, meth, include_private)
21
+ end
29
22
 
30
- if @mailbox == ::Thread.current[:celluloid_mailbox]
31
- args.unshift meth
32
- meth = :__send__
33
- # actor = Thread.current[:celluloid_actor]
34
- # actor = actor.behavior.subject.bare_object
35
- # return actor.__send__(*args, &block)
36
- end
23
+ def method_missing(meth, *args, &block)
24
+ unless @mailbox.alive?
25
+ fail ::Celluloid::DeadActorError, "attempted to call a dead actor"
26
+ end
37
27
 
38
- call = Call::Sync.new(::Celluloid.mailbox, meth, args, block)
39
- @mailbox << call
40
- call.value
41
- end
28
+ if @mailbox == ::Thread.current[:celluloid_mailbox]
29
+ args.unshift meth
30
+ meth = :__send__
31
+ # actor = Thread.current[:celluloid_actor]
32
+ # actor = actor.behavior.subject.bare_object
33
+ # return actor.__send__(*args, &block)
42
34
  end
35
+
36
+ call = ::Celluloid::Call::Sync.new(::Celluloid.mailbox, meth, args, block)
37
+ @mailbox << call
38
+ call.value
43
39
  end
44
40
  end
@@ -1,6 +1,38 @@
1
1
  module Celluloid
2
+ class Actor
3
+ # Handle high-priority system event messages
4
+ def handle_system_event(event)
5
+ if handler = SystemEvent.handle(event.class)
6
+ send(handler, event)
7
+ else
8
+ Internals::Logger.debug "Discarded message (unhandled): #{message}" if $CELLULOID_DEBUG
9
+ end
10
+ end
11
+ end
2
12
  # High-priority internal system events
3
13
  class SystemEvent
14
+ class << self
15
+ @@system_events = {}
16
+ def handle(type)
17
+ @@system_events[type]
18
+ end
19
+
20
+ def handler(&block)
21
+ fail ArgumentError, "SystemEvent handlers must be defined with a block." unless block
22
+ method = begin
23
+ handler = name
24
+ .split("::").last
25
+ .gsub(/([A-Z]+)([A-Z][a-z])/, "\1_\2")
26
+ .gsub(/([a-z\d])([A-Z])/, "\1_\2")
27
+ .tr("-", "_")
28
+ .downcase
29
+ :"handle_#{handler}"
30
+ end
31
+ Actor.send(:define_method, method, &block)
32
+ @@system_events[self] = method
33
+ end
34
+ end
35
+
4
36
  class LinkingEvent < SystemEvent
5
37
  # Shared initializer for LinkingRequest and LinkingResponse
6
38
  def initialize(actor, type)
@@ -15,6 +47,10 @@ module Celluloid
15
47
  class LinkingRequest < SystemEvent::LinkingEvent
16
48
  attr_reader :actor, :type
17
49
 
50
+ handler do |event|
51
+ event.process(links)
52
+ end
53
+
18
54
  def process(links)
19
55
  case type
20
56
  when :link then links << actor
@@ -34,6 +70,11 @@ module Celluloid
34
70
  class ExitEvent < SystemEvent
35
71
  attr_reader :actor, :reason
36
72
 
73
+ handler do |event|
74
+ @links.delete event.actor
75
+ @exit_handler.call(event)
76
+ end
77
+
37
78
  def initialize(actor, reason = nil)
38
79
  @actor = actor
39
80
  @reason = reason
@@ -44,13 +85,22 @@ module Celluloid
44
85
  class NamingRequest < SystemEvent
45
86
  attr_reader :name
46
87
 
88
+ handler do |event|
89
+ @name = event.name
90
+ Celluloid::Probe.actor_named(self) if $CELLULOID_MONITORING
91
+ end
92
+
47
93
  def initialize(name)
48
94
  @name = name
49
95
  end
50
96
  end
51
97
 
52
98
  # Request for an actor to terminate
53
- class TerminationRequest < SystemEvent; end
99
+ class TerminationRequest < SystemEvent
100
+ handler do |event|
101
+ terminate
102
+ end
103
+ end
54
104
 
55
105
  # Signal a condition
56
106
  class SignalConditionRequest < SystemEvent
@@ -60,6 +110,8 @@ module Celluloid
60
110
  end
61
111
  attr_reader :task, :value
62
112
 
113
+ handler(&:call)
114
+
63
115
  def call
64
116
  @task.resume(@value)
65
117
  end