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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3dcad033e3a0b6fa706d2968031433ca348ff7b
4
- data.tar.gz: 7de5d781ae489a2e9887333fbdd17a008f10869c
3
+ metadata.gz: f6f92390f358da4f217db89db7992a0c438e0101
4
+ data.tar.gz: 29023b71e9a2fe46e604bd53237c33cccf9d17e8
5
5
  SHA512:
6
- metadata.gz: d03a5a5da0d7bf0efe4ebf46cb76b58384e7cae02e4c9054e3d7fa15f01c35fb0e7e27f476c0e26d578555945985c1bb65cab1c7e15aeba56c9179a92666247d
7
- data.tar.gz: e8d4f7cf8058919f3ef408a71d8435971e8b01ba3c60c950d38b79dec8a73e7a5c094ad36ba7f599d11fe169c75dc22951014b1584004ddac4796ee4eea7c33c
6
+ metadata.gz: a6420a70030cd7d033a758f05cdb267356998149c8307783c86d8d79679791dd425b971e0f81e9522dd6eb0a158884aecc02fd52c01e2872c30c167d6cfd4ccf
7
+ data.tar.gz: 7e84182dafbf520311afdfed411433da7b2fe8eb9fa694995bab7d5d992c751d7c9f0d4503223612046c38e8979e0d4875593cc9a8ba7f545bef4ad441cc0558
data/CHANGES.md CHANGED
@@ -1,5 +1,13 @@
1
- 0.17.0 (2015)
2
- ----
1
+ 0.17.5 (HEAD)
2
+ -----
3
+ * `Celluloid::ActorSystem` moved to `Celluloid::Actor::System`, and from `celluloid/actor_system.rb` to `celluloid/actor/system.rb`
4
+ * Added extensible API for defining new SystemEvents, and having them handled... without everyone changing `Actor#handle_system_event`.
5
+ * Deprecated Task::TerminatedError & Task::TimeoutError... Consolidated in exceptions.rb, inherited from Exceptions vs. StandardError.
6
+ * General round-up of all "errors" emitted throughout Celluloid, to either be derived from `Celluloid::Error` or `Celluloid::Interruption`.
7
+ * Added ability to pass a block to `Condition#wait` which runs a `{ |value| ... }` type block if present, once the value is obtained by waiting.
8
+
9
+ 0.17.0 (2015-07-04)
10
+ -----
3
11
  * Fix $CELLULOID_TEST warnings
4
12
  * Massive overhaul of test suite, end-to-end.
5
13
  * Make "Terminating task" log messages debug-level events
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2014 Tony Arcieri
1
+ Copyright (c) 2011-2014 Tony Arcieri, Donovan Keme
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  ![Celluloid](https://raw.github.com/celluloid/celluloid-logos/master/celluloid/celluloid.png)
2
2
  =========
3
- [![Gem Version](https://badge.fury.io/rb/celluloid.png)](http://rubygems.org/gems/celluloid)
4
- [![Build Status](https://secure.travis-ci.org/celluloid/celluloid.png?branch=master)](http://travis-ci.org/celluloid/celluloid)
5
- [![Code Climate](https://codeclimate.com/github/celluloid/celluloid.png)](https://codeclimate.com/github/celluloid/celluloid)
6
- [![Coverage Status](https://coveralls.io/repos/celluloid/celluloid/badge.png?branch=master)](https://coveralls.io/r/celluloid/celluloid)
3
+ [![Gem Version](https://badge.fury.io/rb/celluloid.svg)](http://rubygems.org/gems/celluloid)
4
+ [![Build Status](https://secure.travis-ci.org/celluloid/celluloid.svg?branch=master)](http://travis-ci.org/celluloid/celluloid)
5
+ [![Code Climate](https://codeclimate.com/github/celluloid/celluloid.svg)](https://codeclimate.com/github/celluloid/celluloid)
6
+ [![Coverage Status](https://coveralls.io/repos/celluloid/celluloid/badge.svg?branch=master)](https://coveralls.io/r/celluloid/celluloid)
7
7
 
8
8
  > "I thought of objects being like biological cells and/or individual
9
9
  > computers on a network, only able to communicate with messages"
@@ -100,18 +100,24 @@ Related Projects
100
100
  Celluloid is the parent project of a related ecosystem of other projects. If you
101
101
  like Celluloid we definitely recommend you check them out:
102
102
 
103
- * [Celluloid::IO][celluloid-io]: "Evented" IO support for Celluloid actors
104
- * [Celluloid::ZMQ][celluloid-zmq]: "Evented" 0MQ support for Celluloid actors
103
+ * [Reel][reel]: An "evented" web server based on `Celluloid::IO`
105
104
  * [DCell][dcell]: The Celluloid actor protocol distributed over 0MQ
106
- * [Reel][reel]: An "evented" web server based on Celluloid::IO
107
- * [Lattice][lattice]: A concurrent realtime web framework based on Celluloid::IO
105
+ * [ECell][ecell]: Mesh strategies for `Celluloid` actors distributed over 0MQ
106
+ * [Celluloid::IO][celluloid-io]: "Evented" IO support for `Celluloid` actors
107
+ * [Celluloid::ZMQ][celluloid-zmq]: "Evented" 0MQ support for `Celluloid` actors
108
+ * [Celluloid::DNS][celluloid-dns]: An "evented" DNS server based on `Celluloid::IO`
109
+ * [Celluloid::SMTP][celluloid-smtp]: An "evented" SMTP server based on `Celluloid::IO`
110
+ * [Lattice][lattice]: A concurrent realtime web framework based on `Celluloid::IO`
108
111
  * [nio4r][nio4r]: "New IO for Ruby": high performance IO selectors
109
112
  * [Timers][timers]: A generic Ruby timer library for event-based systems
110
113
 
114
+ [reel]: https://github.com/celluloid/reel/
115
+ [dcell]: https://github.com/celluloid/dcell/
116
+ [ecell]: https://github.com/celluloid/ecell/
111
117
  [celluloid-io]: https://github.com/celluloid/celluloid-io/
112
118
  [celluloid-zmq]: https://github.com/celluloid/celluloid-zmq/
113
- [dcell]: https://github.com/celluloid/dcell/
114
- [reel]: https://github.com/celluloid/reel/
119
+ [celluloid-dns]: https://github.com/celluloid/celluloid-dns/
120
+ [celluloid-smtp]: https://github.com/celluloid/celluloid-smtp/
115
121
  [lattice]: https://github.com/celluloid/lattice/
116
122
  [nio4r]: https://github.com/celluloid/nio4r/
117
123
  [timers]: https://github.com/celluloid/timers/
@@ -133,10 +139,16 @@ Or install it yourself as:
133
139
 
134
140
  $ gem install celluloid
135
141
 
136
- Inside of your Ruby program, require Celluloid with:
142
+ Inside of your Ruby program, require Celluloid with [newest API](/celluloid/celluloid/wiki/DEPRECATION-WARNING):
143
+
144
+ ```ruby
145
+ require 'celluloid/current'
146
+ ```
147
+
148
+ Or to support the old API, use:
137
149
 
138
150
  ```ruby
139
- require 'celluloid/autostart'
151
+ require 'celluloid/backported'
140
152
  ```
141
153
 
142
154
  Supported Platforms
@@ -168,5 +180,5 @@ Contributing to Celluloid
168
180
  License
169
181
  -------
170
182
 
171
- Copyright (c) 2011-2014 Tony Arcieri. Distributed under the MIT License. See
172
- LICENSE.txt for further details.
183
+ Copyright (c) 2011-2015 Tony Arcieri, Donovan Keme.
184
+ Distributed under the MIT License. See [LICENSE.txt](https://github.com/celluloid/celluloid/blob/master/LICENSE.txt) for further details.
@@ -8,6 +8,9 @@ benchmark_suite:
8
8
  rubocop:
9
9
  dependency: development
10
10
 
11
+ transpec:
12
+ dependency: development
13
+
11
14
  pry:
12
15
  dependency: development
13
16
 
@@ -17,6 +20,9 @@ rake:
17
20
  rspec:
18
21
  dependency: development
19
22
 
23
+ guard-rspec:
24
+ dependency: development
25
+
20
26
  coveralls:
21
27
  dependency: development
22
28
  gemfile:
@@ -24,10 +30,10 @@ coveralls:
24
30
 
25
31
  celluloid:
26
32
  dependency: core
27
- version: ">= 0.17.0.pre12"
33
+ version: ">= 0.17.0"
28
34
  gemfile:
29
35
  github: celluloid/celluloid
30
- branch: 0.17.0-prerelease
36
+ branch: master
31
37
  submodules: true
32
38
 
33
39
  celluloid-essentials:
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ require "celluloid/autostart"
5
+
6
+ # This example builds on basic_usage.rb to show two things about #async: the
7
+ # (new) fluent API and the preservation of causality order.
8
+ class Stack
9
+ include Celluloid
10
+
11
+ attr_reader :ary
12
+
13
+ def initialize
14
+ @ary = []
15
+ end
16
+
17
+ def push(x)
18
+ @ary.push x
19
+ end
20
+ alias_method :<<, :push
21
+
22
+ def pop
23
+ @ary.pop
24
+ end
25
+
26
+ def show
27
+ p @ary
28
+ end
29
+ end
30
+
31
+ st = Stack.new
32
+
33
+ # Schedule three calls to #push some integers on the stack. They will execute
34
+ # in order because the calls originated as a sequence of method calls in a
35
+ # single thread.
36
+ st.async << 1 << 2 << 3
37
+
38
+ # Schedule a call to show the stack after the three push calls execute.
39
+ st.async.show
40
+
41
+ # Schedule three calls to #pop from the stack.
42
+ st.async.pop.pop.pop
43
+
44
+ # The next (non-async) call is guaranteed to execute after methods previously
45
+ # scheduled in this thread. The causal order of calls (order as requested) is
46
+ # preserved in the execution order.
47
+ st.show
@@ -4,6 +4,7 @@ require "timeout"
4
4
  require "set"
5
5
 
6
6
  $CELLULOID_DEBUG = false
7
+ $CELLULOID_MANAGED ||= false
7
8
 
8
9
  require "celluloid/version"
9
10
  require "celluloid/notices"
@@ -147,7 +148,7 @@ module Celluloid
147
148
  end
148
149
 
149
150
  def init
150
- @actor_system = ActorSystem.new
151
+ @actor_system = Actor::System.new
151
152
  end
152
153
 
153
154
  def start
@@ -163,6 +164,8 @@ module Celluloid
163
164
 
164
165
  # Terminate all actors at exit
165
166
  at_exit do
167
+ sleep 0.126 # hax grace period for unnaturally terminating actors
168
+ # allows "reason" in exit_handler to resolve before being destroyed
166
169
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION >= "1.9"
167
170
  # workaround for MRI bug losing exit status in at_exit block
168
171
  # http://bugs.ruby-lang.org/issues/5218
@@ -313,9 +316,9 @@ module Celluloid
313
316
  # Raise an exception in sender context, but stay running
314
317
  def abort(cause)
315
318
  cause = case cause
316
- when String then RuntimeError.new(cause)
317
- when Exception then cause
318
- else fail TypeError, "Exception object/String expected, but #{cause.class} received"
319
+ when String then RuntimeError.new(cause)
320
+ when Exception then cause
321
+ else fail TypeError, "Exception object/String expected, but #{cause.class} received"
319
322
  end
320
323
  fail AbortError.new(cause)
321
324
  end
@@ -480,7 +483,6 @@ require "celluloid/mailbox/evented"
480
483
  require "celluloid/essentials"
481
484
 
482
485
  require "celluloid/group"
483
- require "celluloid/group/manager"
484
486
  require "celluloid/group/spawner"
485
487
  require "celluloid/group/pool" # TODO: Find way to only load this if being used.
486
488
 
@@ -492,7 +494,8 @@ require "celluloid/actor"
492
494
  require "celluloid/cell"
493
495
  require "celluloid/future"
494
496
 
495
- require "celluloid/actor_system"
497
+ require "celluloid/actor/system"
498
+ require "celluloid/actor/manager"
496
499
 
497
500
  require "celluloid/deprecate" unless $CELLULOID_BACKPORTED == false
498
501
 
@@ -1,4 +1,3 @@
1
-
2
1
  require "timers"
3
2
 
4
3
  module Celluloid
@@ -132,8 +131,9 @@ module Celluloid
132
131
  run
133
132
  end
134
133
 
135
- @proxy = Proxy::Actor.new(@thread, @mailbox)
134
+ @proxy = Proxy::Actor.new(@mailbox, @thread)
136
135
  Celluloid::Probe.actor_created(self) if $CELLULOID_MONITORING
136
+ Celluloid::Actor::Manager.actor_created(self) if $CELLULOID_MANAGED
137
137
  end
138
138
 
139
139
  def behavior_proxy
@@ -167,9 +167,9 @@ module Celluloid
167
167
  end
168
168
 
169
169
  shutdown
170
- rescue Exception => ex
170
+ rescue ::Exception => ex
171
171
  handle_crash(ex)
172
- raise unless ex.is_a? StandardError
172
+ raise unless ex.is_a?(StandardError) || ex.is_a?(Celluloid::Interruption)
173
173
  end
174
174
 
175
175
  # Terminate this actor
@@ -190,7 +190,7 @@ module Celluloid
190
190
  msg.actor.mailbox.address == receiver.mailbox.address &&
191
191
  msg.type == type
192
192
  end
193
- rescue TimeoutError
193
+ rescue TaskTimeout
194
194
  next # IO reactor did something, no message in queue yet.
195
195
  end
196
196
 
@@ -205,7 +205,7 @@ module Celluloid
205
205
  end
206
206
  end
207
207
 
208
- fail TimeoutError, "linking timeout of #{LINKING_TIMEOUT} seconds exceeded with receiver: #{receiver}"
208
+ fail TaskTimeout, "linking timeout of #{LINKING_TIMEOUT} seconds exceeded with receiver: #{receiver}"
209
209
  end
210
210
  end
211
211
 
@@ -247,7 +247,7 @@ module Celluloid
247
247
  bt = caller
248
248
  task = Task.current
249
249
  timer = @timers.after(duration) do
250
- exception = Task::TimeoutError.new("execution expired")
250
+ exception = TaskTimeout.new("execution expired")
251
251
  exception.set_backtrace bt
252
252
  task.resume exception
253
253
  end
@@ -287,31 +287,6 @@ module Celluloid
287
287
  message
288
288
  end
289
289
 
290
- # Handle high-priority system event messages
291
- def handle_system_event(event)
292
- if event.instance_of? ExitEvent
293
- handle_exit_event(event)
294
- elsif event.instance_of? LinkingRequest
295
- event.process(links)
296
- elsif event.instance_of? NamingRequest
297
- @name = event.name
298
- Celluloid::Probe.actor_named(self) if $CELLULOID_MONITORING
299
- elsif event.instance_of? TerminationRequest
300
- terminate
301
- elsif event.instance_of? SignalConditionRequest
302
- event.call
303
- else
304
- Internals::Logger.debug "Discarded message (unhandled): #{message}" if $CELLULOID_DEBUG
305
- end
306
- end
307
-
308
- # Handle exit events received by this actor
309
- def handle_exit_event(event)
310
- @links.delete event.actor
311
-
312
- @exit_handler.call(event)
313
- end
314
-
315
290
  def default_exit_handler(event)
316
291
  fail event.reason if event.reason
317
292
  end
@@ -0,0 +1,7 @@
1
+ module Celluloid
2
+ class Actor
3
+ class Manager
4
+ include Celluloid
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,163 @@
1
+ module Celluloid
2
+ extend Forwardable
3
+ def_delegators :actor_system, :[], :[]=
4
+
5
+ class Actor
6
+ class System
7
+ extend Forwardable
8
+ def_delegators :@registry, :[], :get, :[]=, :set, :delete
9
+
10
+ ROOT_SERVICES = begin
11
+ root_services = [
12
+ {
13
+ as: :notifications_fanout,
14
+ type: Celluloid::Notifications::Fanout,
15
+ },
16
+ {
17
+ as: :incident_reporter,
18
+ type: Celluloid::IncidentReporter,
19
+ args: [STDERR],
20
+ },
21
+ {
22
+ as: :public_services,
23
+ type: Celluloid::Supervision::Service::Public,
24
+ accessors: [:services],
25
+ supervise: [],
26
+ },
27
+ ]
28
+ if $CELLULOID_MANAGED
29
+ root_services << {
30
+ as: :actor_manager,
31
+ type: Celluloid::Actor::Manager,
32
+ accessors: [:manager],
33
+ }
34
+ end
35
+ root_services
36
+ end
37
+
38
+ attr_reader :registry, :group
39
+
40
+ # the root of the supervisor tree is established at supervision/root
41
+
42
+ def root_services
43
+ @tree
44
+ end
45
+
46
+ def root_configuration
47
+ @root
48
+ end
49
+
50
+ def initialize
51
+ @tree = nil
52
+ @group = Celluloid.group_class.new
53
+ @registry = Internals::Registry.new
54
+ @root = ROOT_SERVICES
55
+ end
56
+
57
+ # Launch default services
58
+ def start
59
+ within do
60
+ @root = Supervision::Service::Root.define
61
+ @tree = root_configuration.deploy
62
+ # de root_services[:group_manager].manage! @group
63
+ end
64
+ true
65
+ end
66
+
67
+ def within
68
+ old = Thread.current[:celluloid_actor_system]
69
+ Thread.current[:celluloid_actor_system] = self
70
+ yield
71
+ ensure
72
+ Thread.current[:celluloid_actor_system] = old
73
+ end
74
+
75
+ def get_thread
76
+ @group.get do
77
+ Thread.current[:celluloid_actor_system] = self
78
+ yield
79
+ end
80
+ end
81
+
82
+ def stack_dump
83
+ Internals::Stack::Dump.new(@group)
84
+ end
85
+
86
+ def stack_summary
87
+ Internals::Stack::Summary.new(@group)
88
+ end
89
+
90
+ def registered
91
+ @registry.names
92
+ end
93
+
94
+ def clear_registry
95
+ @registry.clear
96
+ end
97
+
98
+ def running
99
+ actors = []
100
+ @group.each do |t|
101
+ next unless t.role == :actor
102
+ actor = t.actor
103
+
104
+ # NOTE - these are in separate statements, since on JRuby t.actor may
105
+ # become nil befor .behavior_proxy() is called
106
+ next unless actor
107
+ next unless actor.respond_to?(:behavior_proxy)
108
+ proxy = actor.behavior_proxy
109
+ actors << proxy
110
+ end
111
+ actors
112
+ end
113
+
114
+ def running?
115
+ @group.active?
116
+ end
117
+
118
+ # Shut down all running actors
119
+ def shutdown
120
+ actors = running
121
+ Timeout.timeout(shutdown_timeout) do
122
+ Internals::Logger.debug "Terminating #{actors.size} #{(actors.size > 1) ? 'actors' : 'actor'}..." if actors.size > 0
123
+
124
+ # Actors cannot self-terminate, you must do it for them
125
+ actors.each do |actor|
126
+ begin
127
+ actor.terminate!
128
+ rescue DeadActorError
129
+ end
130
+ end
131
+
132
+ actors.each do |actor|
133
+ begin
134
+ Actor.join(actor)
135
+ rescue DeadActorError
136
+ end
137
+ end
138
+ end
139
+ rescue Timeout::Error
140
+ Internals::Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!")
141
+ unless RUBY_PLATFORM == "java" || RUBY_ENGINE == "rbx"
142
+ actors.each do |actor|
143
+ begin
144
+ Actor.kill(actor)
145
+ rescue DeadActorError, MailboxDead
146
+ end
147
+ end
148
+ end
149
+ ensure
150
+ @group.shutdown
151
+ clear_registry
152
+ end
153
+
154
+ def assert_inactive
155
+ @group.assert_inactive
156
+ end
157
+
158
+ def shutdown_timeout
159
+ Celluloid.shutdown_timeout
160
+ end
161
+ end
162
+ end
163
+ end