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.
- checksums.yaml +4 -4
- data/CHANGES.md +10 -2
- data/LICENSE.txt +1 -1
- data/README.md +26 -14
- data/culture/gems/dependencies.yml +8 -2
- data/examples/stack.rb +47 -0
- data/lib/celluloid.rb +9 -6
- data/lib/celluloid/actor.rb +7 -32
- data/lib/celluloid/actor/manager.rb +7 -0
- data/lib/celluloid/actor/system.rb +163 -0
- data/lib/celluloid/call/sync.rb +1 -1
- data/lib/celluloid/calls.rb +3 -3
- data/lib/celluloid/cell.rb +1 -1
- data/lib/celluloid/condition.rb +3 -4
- data/lib/celluloid/debug.rb +1 -0
- data/lib/celluloid/deprecate.rb +3 -0
- data/lib/celluloid/exceptions.rb +20 -15
- data/lib/celluloid/future.rb +40 -3
- data/lib/celluloid/group.rb +5 -9
- data/lib/celluloid/group/pool.rb +1 -1
- data/lib/celluloid/group/spawner.rb +1 -2
- data/lib/celluloid/mailbox.rb +2 -2
- data/lib/celluloid/managed.rb +3 -0
- data/lib/celluloid/notices.rb +1 -1
- data/lib/celluloid/proxies.rb +7 -8
- data/lib/celluloid/proxy/abstract.rb +16 -21
- data/lib/celluloid/proxy/actor.rb +33 -37
- data/lib/celluloid/proxy/async.rb +24 -29
- data/lib/celluloid/proxy/block.rb +20 -24
- data/lib/celluloid/proxy/cell.rb +58 -62
- data/lib/celluloid/proxy/future.rb +33 -37
- data/lib/celluloid/proxy/sync.rb +31 -35
- data/lib/celluloid/system_events.rb +53 -1
- data/lib/celluloid/task.rb +13 -21
- data/lib/celluloid/task/fibered.rb +1 -1
- data/lib/celluloid/task/threaded.rb +2 -2
- data/lib/celluloid/version.rb +1 -1
- data/spec/celluloid/{group → actor}/manager_spec.rb +0 -0
- data/spec/celluloid/{actor_system_spec.rb → actor/system_spec.rb} +4 -4
- data/spec/celluloid/block_spec.rb +64 -3
- data/spec/celluloid/condition_spec.rb +6 -0
- data/spec/celluloid/future_spec.rb +2 -2
- data/spec/deprecate/actor_system_spec.rb +1 -1
- data/spec/deprecate/future_spec.rb +2 -2
- data/spec/shared/actor_examples.rb +20 -4
- data/spec/shared/group_examples.rb +1 -1
- data/spec/shared/mailbox_examples.rb +1 -1
- data/spec/spec_helper.rb +3 -3
- metadata +110 -76
- data/lib/celluloid/actor_system.rb +0 -160
- data/lib/celluloid/group/manager.rb +0 -27
data/lib/celluloid/call/sync.rb
CHANGED
@@ -15,7 +15,7 @@ module Celluloid
|
|
15
15
|
Internals::CallChain.current_id = @chain_id
|
16
16
|
result = super(obj)
|
17
17
|
respond Internals::Response::Success.new(self, result)
|
18
|
-
rescue Exception => ex
|
18
|
+
rescue ::Exception => ex
|
19
19
|
# Exceptions that occur during synchronous calls are reraised in the
|
20
20
|
# context of the sender
|
21
21
|
respond Internals::Response::Error.new(self, ex)
|
data/lib/celluloid/calls.rb
CHANGED
@@ -12,7 +12,7 @@ module Celluloid
|
|
12
12
|
# FIXME: nicer exception
|
13
13
|
fail "Cannot execute blocks on sender in exclusive mode"
|
14
14
|
end
|
15
|
-
@block = Proxy::Block.new(
|
15
|
+
@block = Proxy::Block.new(Celluloid.mailbox, self, block)
|
16
16
|
else
|
17
17
|
@block = nil
|
18
18
|
end
|
@@ -26,10 +26,10 @@ module Celluloid
|
|
26
26
|
check(obj)
|
27
27
|
_b = @block && @block.to_proc
|
28
28
|
obj.public_send(@method, *@arguments, &_b)
|
29
|
-
# rescue Celluloid::
|
29
|
+
# rescue Celluloid::TaskTimeout => ex
|
30
30
|
# raise ex unless ( @retry += 1 ) <= RETRY_CALL_LIMIT
|
31
31
|
# puts "retrying"
|
32
|
-
# Internals::Logger.warn("
|
32
|
+
# Internals::Logger.warn("TaskTimeout at Call dispatch. Retrying in #{RETRY_CALL_WAIT} seconds. ( Attempt #{@retry} of #{RETRY_CALL_LIMIT} )")
|
33
33
|
# sleep RETRY_CALL_WAIT
|
34
34
|
# retry
|
35
35
|
end
|
data/lib/celluloid/cell.rb
CHANGED
@@ -41,7 +41,7 @@ module Celluloid
|
|
41
41
|
end
|
42
42
|
|
43
43
|
@actor.start
|
44
|
-
@proxy = (options[:proxy_class] || Proxy::Cell).new(@actor.
|
44
|
+
@proxy = (options[:proxy_class] || Proxy::Cell).new(@actor.mailbox, @actor.proxy, @subject.class.to_s)
|
45
45
|
end
|
46
46
|
attr_reader :proxy, :subject
|
47
47
|
|
data/lib/celluloid/condition.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Celluloid
|
2
|
-
class ConditionError < Celluloid::Error; end
|
3
|
-
|
4
2
|
# ConditionVariable-like signaling between tasks and threads
|
5
3
|
class Condition
|
6
4
|
class Waiter
|
@@ -21,7 +19,7 @@ module Celluloid
|
|
21
19
|
message = @mailbox.receive(@timeout) do |msg|
|
22
20
|
msg.is_a?(SignalConditionRequest) && msg.task == Thread.current
|
23
21
|
end
|
24
|
-
rescue
|
22
|
+
rescue TimedOut
|
25
23
|
raise ConditionError, "timeout after #{@timeout.inspect} seconds"
|
26
24
|
end until message
|
27
25
|
|
@@ -59,7 +57,8 @@ module Celluloid
|
|
59
57
|
|
60
58
|
result = Celluloid.suspend :condwait, waiter
|
61
59
|
timer.cancel if timer
|
62
|
-
fail result if result.is_a?
|
60
|
+
fail result if result.is_a?(ConditionError)
|
61
|
+
return yield(result) if block_given?
|
63
62
|
result
|
64
63
|
end
|
65
64
|
|
@@ -0,0 +1 @@
|
|
1
|
+
$CELLULOID_DEBUG = true
|
data/lib/celluloid/deprecate.rb
CHANGED
data/lib/celluloid/exceptions.rb
CHANGED
@@ -1,23 +1,28 @@
|
|
1
1
|
module Celluloid
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Trying to do something to a dead actor
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# The sender made an error, not the current actor
|
15
|
-
class AbortError < Celluloid::Error
|
2
|
+
class Error < StandardError; end
|
3
|
+
class Interruption < Exception; end
|
4
|
+
class TimedOut < Celluloid::Interruption; end # Distinguished from `Timeout`
|
5
|
+
class StillActive < Celluloid::Error; end
|
6
|
+
class NotActive < Celluloid::Error; end
|
7
|
+
class NotActorError < Celluloid::Error; end # Don't do Actor-like things outside Actor scope
|
8
|
+
class DeadActorError < Celluloid::Error; end # Trying to do something to a dead actor
|
9
|
+
class NotTaskError < Celluloid::Error; end # Asked to do task-related things outside a task
|
10
|
+
class DeadTaskError < Celluloid::Error; end # Trying to resume a dead task
|
11
|
+
class TaskTerminated < Celluloid::Interruption; end # Kill a running task after terminate
|
12
|
+
class TaskTimeout < Celluloid::TimedOut; end # A timeout occured before the given request could complete
|
13
|
+
class ConditionError < Celluloid::Error; end
|
14
|
+
class AbortError < Celluloid::Error # The sender made an error, not the current actor
|
16
15
|
attr_reader :cause
|
17
|
-
|
18
16
|
def initialize(cause)
|
19
17
|
@cause = cause
|
20
18
|
super "caused by #{cause.inspect}: #{cause}"
|
21
19
|
end
|
22
20
|
end
|
21
|
+
module Feature
|
22
|
+
module Requires
|
23
|
+
class RubiniusOrJRuby < Celluloid::Error; end
|
24
|
+
class Rubinius < Celluloid::Error; end
|
25
|
+
class JRuby < Celluloid::Error; end
|
26
|
+
end
|
27
|
+
end
|
23
28
|
end
|
data/lib/celluloid/future.rb
CHANGED
@@ -8,8 +8,12 @@ module Celluloid
|
|
8
8
|
return super unless block
|
9
9
|
|
10
10
|
future = new
|
11
|
+
task = Thread.current[:celluloid_task]
|
12
|
+
actor = Thread.current[:celluloid_actor]
|
11
13
|
Internals::ThreadHandle.new(Celluloid.actor_system, :future) do
|
12
14
|
begin
|
15
|
+
Thread.current[:celluloid_task] = task
|
16
|
+
Thread.current[:celluloid_actor] = actor
|
13
17
|
call = Call::Sync.new(future, :call, args)
|
14
18
|
call.dispatch(block)
|
15
19
|
rescue
|
@@ -21,12 +25,36 @@ module Celluloid
|
|
21
25
|
|
22
26
|
attr_reader :address
|
23
27
|
|
24
|
-
def initialize
|
28
|
+
def initialize(&block)
|
25
29
|
@address = Celluloid.uuid
|
26
30
|
@mutex = Mutex.new
|
27
31
|
@ready = false
|
28
32
|
@result = nil
|
29
33
|
@forwards = nil
|
34
|
+
@cancelled = false
|
35
|
+
|
36
|
+
if block
|
37
|
+
@call = Call::Sync.new(self, :call, args)
|
38
|
+
Celluloid.internal_pool.get do
|
39
|
+
begin
|
40
|
+
@call.dispatch(block)
|
41
|
+
rescue
|
42
|
+
# Exceptions in blocks will get raised when the value is retrieved
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
@call = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Execute the given method in future context
|
51
|
+
def execute(receiver, method, args, block)
|
52
|
+
@mutex.synchronize do
|
53
|
+
fail "already calling" if @call
|
54
|
+
@call = Call::Sync.new(self, method, args, block)
|
55
|
+
end
|
56
|
+
|
57
|
+
receiver << @call
|
30
58
|
end
|
31
59
|
|
32
60
|
# Check if this future has a value yet
|
@@ -65,15 +93,16 @@ module Celluloid
|
|
65
93
|
end
|
66
94
|
|
67
95
|
if result
|
68
|
-
result.value
|
96
|
+
(result.respond_to?(:value)) ? result.value : result
|
69
97
|
else
|
70
|
-
fail
|
98
|
+
fail TimedOut, "Timed out"
|
71
99
|
end
|
72
100
|
end
|
73
101
|
alias_method :call, :value
|
74
102
|
|
75
103
|
# Signal this future with the given result value
|
76
104
|
def signal(value)
|
105
|
+
return if @cancelled
|
77
106
|
result = Result.new(value, self)
|
78
107
|
|
79
108
|
@mutex.synchronize do
|
@@ -89,6 +118,14 @@ module Celluloid
|
|
89
118
|
end
|
90
119
|
alias_method :<<, :signal
|
91
120
|
|
121
|
+
def cancel(error)
|
122
|
+
response = ErrorResponse.new(@call, error)
|
123
|
+
signal response
|
124
|
+
@mutex.synchronize do
|
125
|
+
@cancelled = true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
92
129
|
# Inspect this Celluloid::Future
|
93
130
|
alias_method :inspect, :to_s
|
94
131
|
|
data/lib/celluloid/group.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
module Celluloid
|
2
2
|
class Group
|
3
|
-
class NotImplemented < StandardError; end
|
4
|
-
class StillActive < StandardError; end
|
5
|
-
class NotActive < StandardError; end
|
6
|
-
|
7
3
|
attr_accessor :group
|
8
4
|
|
9
5
|
def initialize
|
@@ -13,7 +9,7 @@ module Celluloid
|
|
13
9
|
end
|
14
10
|
|
15
11
|
def assert_active
|
16
|
-
fail NotActive unless active?
|
12
|
+
fail Celluloid::NotActive unless active?
|
17
13
|
end
|
18
14
|
|
19
15
|
def assert_inactive
|
@@ -21,7 +17,7 @@ module Celluloid
|
|
21
17
|
if RUBY_PLATFORM == "java"
|
22
18
|
Celluloid.logger.warn "Group is still active"
|
23
19
|
else
|
24
|
-
fail StillActive
|
20
|
+
fail Celluloid::StillActive
|
25
21
|
end
|
26
22
|
end
|
27
23
|
|
@@ -51,15 +47,15 @@ module Celluloid
|
|
51
47
|
end
|
52
48
|
|
53
49
|
def get
|
54
|
-
fail
|
50
|
+
fail NotImplementedError
|
55
51
|
end
|
56
52
|
|
57
53
|
def create
|
58
|
-
fail
|
54
|
+
fail NotImplementedError
|
59
55
|
end
|
60
56
|
|
61
57
|
def shutdown
|
62
|
-
fail
|
58
|
+
fail NotImplementedError
|
63
59
|
end
|
64
60
|
end
|
65
61
|
end
|
data/lib/celluloid/group/pool.rb
CHANGED
@@ -25,7 +25,6 @@ module Celluloid
|
|
25
25
|
th.kill
|
26
26
|
queue << th
|
27
27
|
end
|
28
|
-
|
29
28
|
loop do
|
30
29
|
break if queue.empty?
|
31
30
|
queue.pop.join
|
@@ -52,7 +51,7 @@ module Celluloid
|
|
52
51
|
|
53
52
|
begin
|
54
53
|
proc.call
|
55
|
-
rescue Exception => ex
|
54
|
+
rescue ::Exception => ex
|
56
55
|
Internals::Logger.crash("thread crashed", ex)
|
57
56
|
Thread.current[:celluloid_meta][:state] = :error
|
58
57
|
ensure
|
data/lib/celluloid/mailbox.rb
CHANGED
@@ -70,7 +70,7 @@ module Celluloid
|
|
70
70
|
end
|
71
71
|
|
72
72
|
# Receive a letter from the mailbox. Guaranteed to return a message. If
|
73
|
-
# timeout is exceeded, raise a
|
73
|
+
# timeout is exceeded, raise a TaskTimeout.
|
74
74
|
def receive(timeout = nil, &block)
|
75
75
|
message = nil
|
76
76
|
Timers::Wait.for(timeout) do |remaining|
|
@@ -78,7 +78,7 @@ module Celluloid
|
|
78
78
|
break if message
|
79
79
|
end
|
80
80
|
return message if message
|
81
|
-
fail
|
81
|
+
fail TaskTimeout.new("receive timeout exceeded")
|
82
82
|
end
|
83
83
|
|
84
84
|
# Shut down this mailbox and clean up its contents
|
data/lib/celluloid/notices.rb
CHANGED
@@ -4,7 +4,7 @@ module Celluloid
|
|
4
4
|
@@notices = []
|
5
5
|
|
6
6
|
def backported
|
7
|
-
@@notices << [:
|
7
|
+
@@notices << [:info, "Celluloid #{Celluloid::VERSION} is running in BACKPORTED mode. [ http://git.io/vJf3J ]"]
|
8
8
|
end
|
9
9
|
|
10
10
|
def output
|
data/lib/celluloid/proxies.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Celluloid
|
2
2
|
module Proxy
|
3
|
+
require "celluloid/proxy/abstract"
|
4
|
+
require "celluloid/proxy/sync"
|
5
|
+
require "celluloid/proxy/cell"
|
6
|
+
require "celluloid/proxy/actor"
|
7
|
+
require "celluloid/proxy/async"
|
8
|
+
require "celluloid/proxy/future"
|
9
|
+
require "celluloid/proxy/block"
|
3
10
|
end
|
4
11
|
end
|
5
|
-
|
6
|
-
require "celluloid/proxy/abstract"
|
7
|
-
require "celluloid/proxy/sync"
|
8
|
-
require "celluloid/proxy/cell"
|
9
|
-
require "celluloid/proxy/actor"
|
10
|
-
require "celluloid/proxy/async"
|
11
|
-
require "celluloid/proxy/future"
|
12
|
-
require "celluloid/proxy/block"
|
@@ -1,24 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
Proxy::Abstract
|
8
|
-
end
|
9
|
-
|
10
|
-
# Needed for storing proxies in data structures
|
11
|
-
needed = [:object_id, :__id__, :hash, :private_methods] - instance_methods
|
12
|
-
if needed.any?
|
13
|
-
include ::Kernel.dup.module_eval {
|
14
|
-
undef_method(*(instance_methods - needed))
|
15
|
-
self
|
16
|
-
}
|
1
|
+
# Base class of Celluloid proxies
|
2
|
+
class Celluloid::Proxy::Abstract < BasicObject
|
3
|
+
# Used for reflecting on proxy objects themselves
|
4
|
+
def __class__
|
5
|
+
::Celluloid::Proxy::Abstract
|
6
|
+
end
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
8
|
+
# Needed for storing proxies in data structures
|
9
|
+
needed = [:object_id, :__id__, :hash, :private_methods] - instance_methods
|
10
|
+
if needed.any?
|
11
|
+
include ::Kernel.dup.module_eval {
|
12
|
+
undef_method(*(instance_methods - needed))
|
13
|
+
self
|
14
|
+
}
|
15
|
+
# rubinius bug? These methods disappear when we include hacked kernel
|
16
|
+
define_method :==, ::BasicObject.instance_method(:==) unless instance_methods.include?(:==)
|
17
|
+
alias_method(:equal?, :==) unless instance_methods.include?(:equal?)
|
23
18
|
end
|
24
19
|
end
|
@@ -1,46 +1,42 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class Actor < Abstract
|
5
|
-
attr_reader :thread, :mailbox
|
1
|
+
# A proxy which controls the Actor lifecycle
|
2
|
+
class Celluloid::Proxy::Actor < Celluloid::Proxy::Abstract
|
3
|
+
attr_reader :thread, :mailbox
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
# Used for reflecting on proxy objects themselves
|
6
|
+
def __class__
|
7
|
+
::Celluloid::Proxy::Actor
|
8
|
+
end
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def initialize(mailbox, thread)
|
11
|
+
@mailbox = mailbox
|
12
|
+
@thread = thread
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
def inspect
|
16
|
+
# TODO: use a system event to fetch actor state: tasks?
|
17
|
+
"#<Celluloid::Proxy::Actor(#{@mailbox.address}) alive>"
|
18
|
+
rescue DeadActorError
|
19
|
+
"#<Celluloid::Proxy::Actor(#{@mailbox.address}) dead>"
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
def alive?
|
23
|
+
@mailbox.alive?
|
24
|
+
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
def dead?
|
27
|
+
!alive?
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
# Terminate the associated actor
|
31
|
+
def terminate
|
32
|
+
terminate!
|
33
|
+
::Celluloid::Actor.join(self)
|
34
|
+
nil
|
35
|
+
end
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
37
|
+
# Terminate the associated actor asynchronously
|
38
|
+
def terminate!
|
39
|
+
::Kernel.raise ::Celluloid::DeadActorError, "actor already terminated" unless alive?
|
40
|
+
@mailbox << ::Celluloid::TerminationRequest.new
|
45
41
|
end
|
46
42
|
end
|