celluloid 0.18.0.pre → 0.18.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +114 -39
  3. data/CONDUCT.md +13 -0
  4. data/CONTRIBUTING.md +39 -0
  5. data/README.md +59 -55
  6. data/architecture.md +120 -0
  7. data/examples/basic_usage.rb +1 -1
  8. data/examples/configurations.rb +78 -0
  9. data/examples/futures.rb +1 -1
  10. data/examples/ring.rb +5 -4
  11. data/examples/simple_pmap.rb +1 -1
  12. data/examples/stack.rb +2 -2
  13. data/examples/supervisors_and_registry.rb +82 -0
  14. data/examples/timers.rb +1 -1
  15. data/lib/celluloid.rb +72 -47
  16. data/lib/celluloid/actor.rb +27 -17
  17. data/lib/celluloid/actor/system.rb +13 -29
  18. data/lib/celluloid/autostart.rb +5 -5
  19. data/lib/celluloid/backported.rb +6 -2
  20. data/lib/celluloid/call/async.rb +2 -0
  21. data/lib/celluloid/call/sync.rb +10 -3
  22. data/lib/celluloid/calls.rb +5 -12
  23. data/lib/celluloid/cell.rb +5 -9
  24. data/lib/celluloid/condition.rb +3 -3
  25. data/lib/celluloid/core_ext.rb +0 -2
  26. data/lib/celluloid/current.rb +3 -1
  27. data/lib/celluloid/debug.rb +3 -0
  28. data/lib/celluloid/exceptions.rb +2 -2
  29. data/lib/celluloid/future.rb +7 -9
  30. data/lib/celluloid/group.rb +12 -8
  31. data/lib/celluloid/group/pool.rb +1 -3
  32. data/lib/celluloid/group/spawner.rb +2 -6
  33. data/lib/celluloid/internals/call_chain.rb +15 -0
  34. data/lib/celluloid/internals/cpu_counter.rb +62 -0
  35. data/lib/celluloid/internals/handlers.rb +42 -0
  36. data/lib/celluloid/internals/links.rb +38 -0
  37. data/lib/celluloid/internals/logger.rb +104 -0
  38. data/lib/celluloid/internals/method.rb +34 -0
  39. data/lib/celluloid/internals/properties.rb +32 -0
  40. data/lib/celluloid/internals/receivers.rb +64 -0
  41. data/lib/celluloid/internals/registry.rb +102 -0
  42. data/lib/celluloid/internals/responses.rb +46 -0
  43. data/lib/celluloid/internals/signals.rb +24 -0
  44. data/lib/celluloid/internals/stack.rb +74 -0
  45. data/lib/celluloid/internals/stack/dump.rb +12 -0
  46. data/lib/celluloid/internals/stack/states.rb +72 -0
  47. data/lib/celluloid/internals/stack/summary.rb +12 -0
  48. data/lib/celluloid/internals/task_set.rb +51 -0
  49. data/lib/celluloid/internals/thread_handle.rb +52 -0
  50. data/lib/celluloid/internals/uuid.rb +40 -0
  51. data/lib/celluloid/logging/incident.rb +21 -0
  52. data/lib/celluloid/logging/incident_logger.rb +147 -0
  53. data/lib/celluloid/logging/incident_reporter.rb +49 -0
  54. data/lib/celluloid/logging/log_event.rb +20 -0
  55. data/lib/celluloid/logging/ring_buffer.rb +64 -0
  56. data/lib/celluloid/mailbox.rb +22 -9
  57. data/lib/celluloid/mailbox/evented.rb +13 -5
  58. data/lib/celluloid/managed.rb +6 -3
  59. data/lib/celluloid/notifications.rb +95 -0
  60. data/lib/celluloid/pool.rb +6 -0
  61. data/lib/celluloid/probe.rb +81 -0
  62. data/lib/celluloid/proxy/abstract.rb +9 -9
  63. data/lib/celluloid/proxy/async.rb +1 -1
  64. data/lib/celluloid/proxy/block.rb +2 -2
  65. data/lib/celluloid/proxy/cell.rb +1 -1
  66. data/lib/celluloid/proxy/future.rb +2 -4
  67. data/lib/celluloid/proxy/sync.rb +1 -3
  68. data/lib/celluloid/rspec.rb +22 -33
  69. data/lib/celluloid/supervision.rb +17 -0
  70. data/lib/celluloid/supervision/configuration.rb +169 -0
  71. data/lib/celluloid/supervision/configuration/injections.rb +8 -0
  72. data/lib/celluloid/supervision/configuration/instance.rb +113 -0
  73. data/lib/celluloid/supervision/constants.rb +123 -0
  74. data/lib/celluloid/supervision/container.rb +144 -0
  75. data/lib/celluloid/supervision/container/behavior.rb +89 -0
  76. data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
  77. data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
  78. data/lib/celluloid/supervision/container/injections.rb +8 -0
  79. data/lib/celluloid/supervision/container/instance.rb +116 -0
  80. data/lib/celluloid/supervision/container/pool.rb +210 -0
  81. data/{culture/rubocop/perf.yml → lib/celluloid/supervision/container/tree.rb} +0 -0
  82. data/lib/celluloid/supervision/deprecate.rb +9 -0
  83. data/lib/celluloid/supervision/deprecate/supervise.rb +105 -0
  84. data/lib/celluloid/supervision/deprecate/validation.rb +54 -0
  85. data/lib/celluloid/supervision/service.rb +27 -0
  86. data/lib/celluloid/supervision/supervise.rb +34 -0
  87. data/lib/celluloid/supervision/validation.rb +40 -0
  88. data/lib/celluloid/supervision/version.rb +5 -0
  89. data/lib/celluloid/system_events.rb +11 -6
  90. data/lib/celluloid/task.rb +25 -12
  91. data/lib/celluloid/task/fibered.rb +2 -0
  92. data/lib/celluloid/task/threaded.rb +3 -3
  93. data/lib/celluloid/test.rb +5 -2
  94. data/lib/celluloid/thread.rb +0 -2
  95. data/lib/celluloid/version.rb +1 -1
  96. data/spec/celluloid/block_spec.rb +29 -32
  97. data/spec/celluloid/calls_spec.rb +5 -15
  98. data/spec/celluloid/future_spec.rb +2 -2
  99. data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
  100. data/spec/celluloid/internals/links_spec.rb +43 -0
  101. data/spec/celluloid/internals/properties_spec.rb +40 -0
  102. data/spec/celluloid/internals/registry_spec.rb +62 -0
  103. data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
  104. data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
  105. data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
  106. data/spec/celluloid/internals/uuid_spec.rb +9 -0
  107. data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
  108. data/spec/celluloid/mailbox/evented_spec.rb +11 -22
  109. data/spec/celluloid/misc/leak_spec.rb +3 -4
  110. data/spec/celluloid/notifications_spec.rb +140 -0
  111. data/spec/celluloid/probe_spec.rb +102 -0
  112. data/spec/celluloid/proxy_spec.rb +30 -30
  113. data/spec/celluloid/supervision/behavior_spec.rb +74 -0
  114. data/spec/celluloid/supervision/configuration_spec.rb +181 -0
  115. data/spec/celluloid/supervision/container_spec.rb +72 -0
  116. data/spec/celluloid/supervision/instance_spec.rb +13 -0
  117. data/spec/celluloid/supervision/root_spec.rb +28 -0
  118. data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
  119. data/spec/celluloid/task/fibered_spec.rb +1 -3
  120. data/spec/celluloid/task/threaded_spec.rb +1 -3
  121. data/spec/shared/actor_examples.rb +58 -33
  122. data/spec/shared/group_examples.rb +2 -2
  123. data/spec/shared/mailbox_examples.rb +1 -1
  124. data/spec/shared/stack_examples.rb +87 -0
  125. data/spec/shared/task_examples.rb +2 -3
  126. data/spec/spec_helper.rb +2 -4
  127. data/spec/support/configure_rspec.rb +2 -3
  128. data/spec/support/coverage.rb +2 -4
  129. data/spec/support/crash_checking.rb +2 -2
  130. data/spec/support/examples/actor_class.rb +3 -8
  131. data/spec/support/examples/call_class.rb +2 -2
  132. data/spec/support/examples/container_class.rb +35 -0
  133. data/spec/support/examples/evented_mailbox_class.rb +1 -2
  134. data/spec/support/examples/stack_classes.rb +58 -0
  135. data/spec/support/examples/stack_methods.rb +23 -0
  136. data/spec/support/examples/subordinate_class.rb +19 -0
  137. data/spec/support/logging.rb +2 -34
  138. data/spec/support/loose_threads.rb +3 -16
  139. data/spec/support/reset_class_variables.rb +5 -1
  140. data/spec/support/stubbing.rb +1 -1
  141. metadata +91 -316
  142. data/culture/CONDUCT.md +0 -38
  143. data/culture/GSoC/1010-why_we_will_participate.md +0 -17
  144. data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
  145. data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
  146. data/culture/GSoC/1040-getting_students_involved.md +0 -5
  147. data/culture/GSoC/1050-student_involvement_after.md +0 -5
  148. data/culture/GSoC/README.md +0 -16
  149. data/culture/Gemfile +0 -9
  150. data/culture/LICENSE.txt +0 -22
  151. data/culture/README.md +0 -22
  152. data/culture/Rakefile +0 -5
  153. data/culture/SYNC.md +0 -70
  154. data/culture/celluloid-culture.gemspec +0 -18
  155. data/culture/gems/README.md +0 -39
  156. data/culture/gems/dependencies.yml +0 -93
  157. data/culture/gems/loader.rb +0 -101
  158. data/culture/rubocop/README.md +0 -38
  159. data/culture/rubocop/lint.yml +0 -8
  160. data/culture/rubocop/metrics.yml +0 -15
  161. data/culture/rubocop/rubocop.yml +0 -5
  162. data/culture/rubocop/style.yml +0 -61
  163. data/culture/spec/gems_spec.rb +0 -2
  164. data/culture/spec/spec_helper.rb +0 -0
  165. data/culture/spec/sync_spec.rb +0 -2
  166. data/culture/sync.rb +0 -56
  167. data/culture/tasks/rspec.rake +0 -5
  168. data/culture/tasks/rubocop.rake +0 -2
  169. data/lib/celluloid/actor/manager.rb +0 -7
  170. data/lib/celluloid/deprecate.rb +0 -34
  171. data/lib/celluloid/fiber.rb +0 -32
  172. data/lib/celluloid/notices.rb +0 -15
  173. data/spec/deprecate/actor_system_spec.rb +0 -72
  174. data/spec/deprecate/block_spec.rb +0 -52
  175. data/spec/deprecate/calls_spec.rb +0 -39
  176. data/spec/deprecate/evented_mailbox_spec.rb +0 -34
  177. data/spec/deprecate/future_spec.rb +0 -32
  178. data/spec/deprecate/internal_pool_spec.rb +0 -4
  179. data/spec/support/env.rb +0 -21
@@ -0,0 +1,120 @@
1
+ # Architecture
2
+
3
+ The purpose of this document is to provide an overview of the `Celluloid` project architecture. It is intended as a learning tool for
4
+ GSoC (Google Summer of Code) and for anyone else interested in peeking under the hood to figure out how Celluloid works.
5
+
6
+ This document will evolve since the people writing it are learning the project too. It will likely evolve in the following manner:
7
+
8
+ 1. Document all major classes by describing the purpose of each one.
9
+ 2. Document the dependencies between classes described in item 1.
10
+ 3. Describe the flow of messages between the classes documented in items 1 and 2.
11
+ 4. Generate a Big Picture overview of the overall Celluloid architecture.
12
+ 5. Create a flew graphics to depict class dependencies and message flows (perhaps as a directed acyclic graph).
13
+
14
+ ## Document Status
15
+
16
+ The document is working on item 1.
17
+
18
+ ## Required Libraries
19
+ `logger`
20
+ `thread`
21
+ `timeout`
22
+ `set`
23
+
24
+ ## Require Lifecycle
25
+ Document the steps taken from the moment `require "celluloid"` is executed by the runtime.
26
+
27
+ The file `celluloid.rb` is read in by the runtime. This file requires some standard libraries like `Thread` and `Set` (see Required Libraries for full list) and initializes the `Celluloid` module namespace. It then sets up a Celluloid singleton class which will contain utility functions that need to be accessed from anywhere. Think of these singleton methods as global methods. These specific methods should be considered private to the library and should not be directly called by user code.
28
+
29
+ From here it continues to `extend` and `include` other modules so that any Ruby object that executes `include Celluloid` as part of its class definition automatically gains all of the Celluloid magic.
30
+
31
+ Next, it defines regular methods within the Celluloid namespace. These are also global methods but they are essentially the public API to the outside world. These methods (such as `current_actor` and `terminate`) can be called by user code.
32
+
33
+ Next we have a list of `require`'d subfiles. This loads the remainder of the library in preparation to start running.
34
+
35
+ Next, the code sets up two global default settings for the `task_class` and `group_class`. I don't know what these are yet but by exposing them this way it's clearly intended for these items to be defined in such a way that user code can override them with use-case-specific code. The code here can also read names from the environment variables to set the defaults. This is likely intended for use by the spec/test system.
36
+
37
+ Lastly, the code registers some methods for shutdown to terminate all actors `at_exit` and then initializes the system.
38
+
39
+ To boot the system, call `require 'celluloid'`.
40
+
41
+ ## Supervision Lifecycle
42
+ The final call to `Actor::System.new.start` kicks off the top level supervisor. The supervisor container is an actor and it will keep track of all defined actors as they are added for supervision. A user may create an actor that is not supervised, so the top-level supervisor does not necessarily have a reference to every actor in the system.
43
+
44
+ The Registry is also created at this time and lives within the main container. Actors can be added to the registry even if they are not supervised. The two concepts are separate even though the code is somewhat comingled.
45
+
46
+ ## Classes / Modules
47
+
48
+ ### Celluloid Module
49
+ * Sets up class accessors used throughout/globally such as `logger`
50
+ * When using `include Celluloid` on a class, it performs the following work during `include`:
51
+ * Extends `ClassMethods` and `Internals::Properties`
52
+ * Includes `InstanceMethods`
53
+ * Sets properties on the class object.
54
+ * Removes `trap_exit` and `exclusive` if they exist on the singleton class so that Celluloid can redefine them for itself.
55
+ * Defines class methods inside the `Celluloid` namespace such as `actor?` and `mailbox` and `cores`. These are utility functions. They are defined on the Celluloid singleton.
56
+ * Provides the entry method `boot` to start up the whole system and its opposite `shutdown` to terminate everything.
57
+
58
+ #### Depends On Classes
59
+ * Internals::Logger
60
+ * Internals::CallChain
61
+ * Actor::System
62
+ * Celluloid::Mailbox
63
+ * Thread (primarily for Thread.current to access fiber locals like `:celluloid_actor`)
64
+ * Future
65
+
66
+ ### ClassMethods Module
67
+ This class contains class-level methods which are added to every user class that contains `include Celluloid`.
68
+
69
+ * Overrides `new` for the class object.
70
+
71
+ #### Depends On Classes
72
+ * Cell
73
+ * Actor
74
+ * Celluloid
75
+
76
+ ### InstanceMethods Module
77
+ This module contains instance-level methods which are added to every user class that contains `include Celluloid`.
78
+
79
+ #### Depends on Classes
80
+ * Actor
81
+ * Celluloid
82
+
83
+
84
+ ### Actor::System class
85
+ Is created and `start`'ed as part of the entire boot sequence. This class provides essential services utilized by the rest of the library such as the Registry and the top-level Supervisor.
86
+
87
+ #### Lifecycle
88
+ Creates the `Registry` and initializes the `Celluloid.group_class`. Upon `start` it makes sure that it switches the `Thread.current[:celluloid_actor_system]` to itself, then defines and deploys the `Root` services.
89
+
90
+ #### Depends On Classes
91
+ * Supervision::Service::Root which is in gem `celluloid-supervision`
92
+ * Celluloid::Notifications::Fanout
93
+ * Celluloid::IncidentReporter
94
+ * Celluloid::Supervision::Service::Public
95
+ * Celluloid::Actor::Manager
96
+ * Celluloid
97
+ * Internals::Registry
98
+ * Celluloid.group_class
99
+
100
+ ## Gem - celluloid-supervision
101
+ Necessary for the core system to boot.
102
+
103
+ Really has only two classes/modules of note. One is Supervision::Container which is an actor that keeps track of all actors under supervision. It also handles restart. Two is Supervision::Configuration. This class manages the several different ways that an actor may be placed under supervision, arguments passed to it, and other data.
104
+
105
+ Be careful when reading the code. Each file in the gem relies on open Ruby classes. These files reopen previously defined classes and add more behavior, so to get a complete picture for what the Configuration and Container classes can do you must look through all of the files. While this logical separation of business logic to its own file is neat, it adds to the cognitive load when reading the code since the entire class defintion is spread over multiple files.
106
+
107
+ ### Supervision::Service::Root
108
+
109
+ #### Depends On Classes
110
+ * Supervision::Container
111
+
112
+
113
+ ### Supervision::Container
114
+ Stores references to Actors on behalf of a Supervisor.
115
+
116
+ This is the only class under the `Supervision` namespace that is an Actor. Every other class is a regular Ruby class.
117
+
118
+ #### Depends On Classes
119
+ * Supervision::Configuration
120
+ *
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/autostart"
5
5
 
6
6
  class Counter
@@ -0,0 +1,78 @@
1
+ require "celluloid/current"
2
+
3
+ puts "Use Supervision::Configuration objects!"
4
+
5
+ class Hello
6
+ include Celluloid
7
+
8
+ finalizer :ceasing
9
+
10
+ def initialize(to)
11
+ @to = to
12
+ puts "Created Hello #{@to}"
13
+ end
14
+
15
+ def ceasing
16
+ puts "Hello #{@to} go buhbye"
17
+ end
18
+ end
19
+
20
+ class FooBar
21
+ include Celluloid
22
+
23
+ finalizer :ceasing
24
+
25
+ def initialize(i = 0)
26
+ @i = i
27
+ puts "Created FooBar: #{@i}"
28
+ end
29
+
30
+ def ceasing
31
+ puts "FooBar FooBar: #{@i} go buhbye"
32
+ end
33
+ end
34
+
35
+ puts "\nInstantiated in bulk, using #deploy"
36
+
37
+ config = Celluloid::Supervision::Configuration.define([
38
+ { type: FooBar, as: :foobar },
39
+ { type: Hello, as: :hello, args: ["World"] }
40
+ ])
41
+
42
+ config.deploy
43
+ puts "...shut it down"
44
+ config.shutdown
45
+
46
+ puts "\nInstantiated in bulk, using .deploy"
47
+
48
+ config = Celluloid::Supervision::Configuration.deploy([
49
+ { type: FooBar, as: :foobar, args: [1] },
50
+ { type: Hello, as: :hello, args: ["World"] }
51
+ ])
52
+
53
+ puts "...shut it down"
54
+ config.shutdown
55
+
56
+ puts "\nInstantiated two actors individually, using a local configuration object"
57
+
58
+ config = Celluloid::Supervision::Configuration.new
59
+ config.define type: FooBar, as: :foobar11, args: [11]
60
+ config.define type: FooBar, as: :foobar33, args: [33]
61
+ config.deploy
62
+
63
+ puts "Instantiated another, which starts automatically."
64
+ puts "... using the local configuration object"
65
+ puts "... using a lazy loaded argument"
66
+ config.add type: Hello, as: :hello, args: -> { "Spinning World" }
67
+
68
+ config.shutdown
69
+
70
+ puts "\nReuse our last configuration!"
71
+
72
+ config.deploy
73
+ puts "...shut it down"
74
+ config.shutdown
75
+
76
+ puts "Thinking for 4 seconds, and 4 seconds only."
77
+ sleep 4
78
+ puts "Use Supervision::Configuration objects. Really!"
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/autostart"
5
5
  require "digest/sha2"
6
6
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/autostart"
5
5
 
6
6
  class Ring
@@ -28,7 +28,7 @@ class Ring
28
28
 
29
29
  # Go around the ring the given number of times
30
30
  def run(n)
31
- fail ArgumentError, "I can't go around a negative number of times" if n < 0
31
+ raise ArgumentError, "I can't go around a negative number of times" if n < 0
32
32
 
33
33
  async.around n
34
34
  wait :done
@@ -48,14 +48,15 @@ if $PROGRAM_NAME == __FILE__
48
48
  require "benchmark"
49
49
  SIZE = 512
50
50
  TIMES = 10
51
+ ring = nil
51
52
 
52
53
  puts "*** Creating a #{SIZE} node ring..."
53
54
  puts Benchmark.measure {
54
- $ring = Ring.new(SIZE)
55
+ ring = Ring.new(SIZE)
55
56
  }
56
57
 
57
58
  puts "*** Sending a message around #{TIMES} times"
58
59
  puts Benchmark.measure {
59
- $ring.run(TIMES)
60
+ ring.run(TIMES)
60
61
  }
61
62
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/autostart"
5
5
 
6
6
  module Enumerable
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/autostart"
5
5
 
6
6
  # This example builds on basic_usage.rb to show two things about #async: the
@@ -17,7 +17,7 @@ class Stack
17
17
  def push(x)
18
18
  @ary.push x
19
19
  end
20
- alias_method :<<, :push
20
+ alias << push
21
21
 
22
22
  def pop
23
23
  @ary.pop
@@ -0,0 +1,82 @@
1
+ require "celluloid/autostart"
2
+
3
+ class MyActor
4
+ include Celluloid
5
+ attr_reader :state
6
+
7
+ def initialize
8
+ @state = :clean
9
+ end
10
+
11
+ def broken_method
12
+ @state = :dirty
13
+ oh_crap_im_totally_broken
14
+ end
15
+ end
16
+
17
+ #
18
+ # Using the Supervisor API directly
19
+ #
20
+
21
+ puts "*** Demonstrating using the Supervisor API directly"
22
+
23
+ # Calling supervise directly returns the supervisor
24
+ supervisor = MyActor.supervise
25
+
26
+ # We can get to the current version of an actor by calling
27
+ # Celluloid::Supervisor#actors. This prints ':clean'
28
+ puts "We should be in a clean state now: #{supervisor.actors.first.state}"
29
+ puts "Brace yourself for a crash message..."
30
+
31
+ # If we call a method that crashes an actor, it will print out a debug message,
32
+ # then restart an actor in a clean state
33
+ begin
34
+ supervisor.actors.first.broken_method
35
+ rescue NameError
36
+ puts "Uhoh, we crashed the actor..."
37
+ end
38
+
39
+ puts "The supervisor should automatically restart the actor"
40
+
41
+ # By now we'll be back in a :clean state!
42
+ begin
43
+ puts "We should now be in a clean state again: #{supervisor.actors.first.state}"
44
+ rescue Celluloid::DeadActorError
45
+ # Perhaps we got ahold of the actor before the supervisor restarted it
46
+ retry
47
+ end
48
+
49
+ #
50
+ # Using the Actor Registry
51
+ # This is the preferred approach and will make using DCell easier
52
+ #
53
+
54
+ puts "*** Demonstrating using the actor registry"
55
+
56
+ # We can give our actor a name and thus avoid interacting with the supervisor
57
+ MyActor.supervise as: :my_actor
58
+
59
+ # Same as above, just getting the actor from a different place
60
+ puts "We should be in a clean state now: #{Celluloid::Actor[:my_actor].state}"
61
+ puts "Brace yourself for a crash message..."
62
+
63
+ # If we call a method that crashes an actor, it will print out a debug message,
64
+ # then restart an actor in a clean state
65
+ begin
66
+ Celluloid::Actor[:my_actor].broken_method
67
+ rescue NameError
68
+ puts "Uhoh, we crashed the actor..."
69
+ end
70
+
71
+ puts "The supervisor should automatically restart the actor"
72
+
73
+ # By now we'll be back in a :clean state!
74
+ begin
75
+ puts "We should now be in a clean state again: #{Celluloid::Actor[:my_actor].state}"
76
+ rescue Celluloid::DeadActorError
77
+ # Perhaps we got ahold of the actor before the supervisor restarted it
78
+ # Don't want to catch Celluloid::DeadActorError all over the place? If this
79
+ # code were in a supervised Celluloid::Actor itself, the supervisor would
80
+ # catch Celluloid::DeadActorError and automatically restart this actor
81
+ retry
82
+ end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
4
  require "celluloid/current"
5
5
 
6
6
  class TimerExample
@@ -1,17 +1,17 @@
1
+ # TODO: eliminate use of global variables
2
+ require "English"
3
+
1
4
  require "logger"
2
- require "thread"
3
- require "timeout"
4
5
  require "set"
6
+ require "timeout"
5
7
 
8
+ # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
9
+ # rubocop:disable Style/GlobalVars
6
10
  $CELLULOID_DEBUG = false
7
- $CELLULOID_MANAGED ||= false
11
+ $CELLULOID_MONITORING = false
12
+ # rubocop:enable Style/GlobalVars
8
13
 
9
14
  require "celluloid/version"
10
- require "celluloid/notices"
11
-
12
- $CELLULOID_BACKPORTED = false if defined?(CELLULOID_FUTURE) && CELLULOID_FUTURE
13
- $CELLULOID_BACKPORTED = (ENV["CELLULOID_BACKPORTED"] != "false") unless defined?($CELLULOID_BACKPORTED)
14
- Celluloid::Notices.backported if $CELLULOID_BACKPORTED
15
15
 
16
16
  module Celluloid
17
17
  # Expose all instance methods as singleton methods
@@ -21,7 +21,7 @@ module Celluloid
21
21
  LINKING_TIMEOUT = 5
22
22
 
23
23
  # Warning message added to Celluloid objects accessed outside their actors
24
- BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT "
24
+ BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT ".freeze
25
25
 
26
26
  class << self
27
27
  attr_writer :actor_system # Default Actor System
@@ -33,9 +33,11 @@ module Celluloid
33
33
 
34
34
  def actor_system
35
35
  if Thread.current.celluloid?
36
- Thread.current[:celluloid_actor_system] || fail(Error, "actor system not running")
36
+ Thread.current[:celluloid_actor_system] || raise(Error, "actor system not running")
37
37
  else
38
- Thread.current[:celluloid_actor_system] || @actor_system || fail(Error, "Celluloid is not yet started; use Celluloid.boot")
38
+ Thread.current[:celluloid_actor_system] ||
39
+ @actor_system ||
40
+ raise(Error, "Celluloid is not yet started; use Celluloid.boot")
39
41
  end
40
42
  end
41
43
 
@@ -54,15 +56,23 @@ module Celluloid
54
56
  klass.property :exclusive_actor, default: false
55
57
  klass.property :exclusive_methods, multi: true
56
58
  klass.property :execute_block_on_receiver,
57
- default: [:after, :every, :receive],
59
+ default: %i[after every receive],
58
60
  multi: true
59
61
 
60
62
  klass.property :finalizer
61
63
  klass.property :exit_handler_name
62
64
 
63
65
  singleton = class << klass; self; end
64
- singleton.send(:remove_method, :trap_exit) rescue nil
65
- singleton.send(:remove_method, :exclusive) rescue nil
66
+ begin
67
+ singleton.send(:remove_method, :trap_exit)
68
+ rescue
69
+ nil
70
+ end
71
+ begin
72
+ singleton.send(:remove_method, :exclusive)
73
+ rescue
74
+ nil
75
+ end
66
76
 
67
77
  singleton.send(:define_method, :trap_exit) do |*args|
68
78
  exit_handler_name(*args)
@@ -96,20 +106,20 @@ module Celluloid
96
106
  def cores
97
107
  Internals::CPUCounter.cores
98
108
  end
99
- alias_method :cpus, :cores
100
- alias_method :ncpus, :cores
109
+ alias cpus cores
110
+ alias ncpus cores
101
111
 
102
112
  # Perform a stack dump of all actors to the given output object
103
113
  def stack_dump(output = STDERR)
104
114
  actor_system.stack_dump.print(output)
105
115
  end
106
- alias_method :dump, :stack_dump
116
+ alias dump stack_dump
107
117
 
108
118
  # Perform a stack summary of all actors to the given output object
109
119
  def stack_summary(output = STDERR)
110
120
  actor_system.stack_summary.print(output)
111
121
  end
112
- alias_method :summarize, :stack_summary
122
+ alias summarize stack_summary
113
123
 
114
124
  def public_registry
115
125
  actor_system.public_registry
@@ -157,14 +167,16 @@ module Celluloid
157
167
 
158
168
  def running?
159
169
  actor_system && actor_system.running?
170
+ rescue Error
171
+ false
160
172
  end
161
173
 
162
- #de TODO Anticipate outside process finalizer that would by-pass this.
174
+ # de TODO Anticipate outside process finalizer that would by-pass this.
163
175
  def register_shutdown
164
176
  return if defined?(@shutdown_registered) && @shutdown_registered
165
177
  # Terminate all actors at exit, unless the exit is abnormal.
166
178
  at_exit do
167
- Celluloid.shutdown unless $!
179
+ Celluloid.shutdown unless $ERROR_INFO
168
180
  end
169
181
  @shutdown_registered = true
170
182
  end
@@ -172,6 +184,7 @@ module Celluloid
172
184
  # Shut down all running actors
173
185
  def shutdown
174
186
  actor_system.shutdown
187
+ @actor_system = nil
175
188
  end
176
189
 
177
190
  def version
@@ -186,18 +199,18 @@ module Celluloid
186
199
  proxy._send_(:initialize, *args, &block)
187
200
  proxy
188
201
  end
189
- alias_method :spawn, :new
202
+ alias spawn new
190
203
 
191
204
  # Create a new actor and link to the current one
192
205
  def new_link(*args, &block)
193
- fail NotActorError, "can't link outside actor context" unless Celluloid.actor?
206
+ raise NotActorError, "can't link outside actor context" unless Celluloid.actor?
194
207
 
195
208
  proxy = Cell.new(allocate, behavior_options, actor_options).proxy
196
209
  Actor.link(proxy)
197
210
  proxy._send_(:initialize, *args, &block)
198
211
  proxy
199
212
  end
200
- alias_method :spawn_link, :new_link
213
+ alias spawn_link new_link
201
214
 
202
215
  # Run an actor in the foreground
203
216
  def run(*args, &block)
@@ -215,7 +228,7 @@ module Celluloid
215
228
  mailbox_class: mailbox_class,
216
229
  mailbox_size: mailbox_size,
217
230
  task_class: task_class,
218
- exclusive: exclusive_actor,
231
+ exclusive: exclusive_actor
219
232
  }
220
233
  end
221
234
 
@@ -225,7 +238,7 @@ module Celluloid
225
238
  exclusive_methods: exclusive_methods,
226
239
  exit_handler_name: exit_handler_name,
227
240
  finalizer: finalizer,
228
- receiver_block_executions: execute_block_on_receiver,
241
+ receiver_block_executions: execute_block_on_receiver
229
242
  }
230
243
  end
231
244
 
@@ -253,7 +266,7 @@ module Celluloid
253
266
  def bare_object
254
267
  self
255
268
  end
256
- alias_method :wrapped_object, :bare_object
269
+ alias wrapped_object bare_object
257
270
 
258
271
  # Are we being invoked in a different thread from our owner?
259
272
  def leaked?
@@ -269,18 +282,18 @@ module Celluloid
269
282
  def registered_name
270
283
  Actor.registered_name
271
284
  end
272
- alias_method :name, :registered_name
285
+ alias name registered_name
273
286
 
274
287
  def inspect
275
288
  return "..." if Celluloid.detect_recursion
276
289
 
277
290
  str = "#<"
278
291
 
279
- if leaked?
280
- str << Celluloid::BARE_OBJECT_WARNING_MESSAGE
281
- else
282
- str << "Celluloid::Proxy::Cell"
283
- end
292
+ str << if leaked?
293
+ Celluloid::BARE_OBJECT_WARNING_MESSAGE
294
+ else
295
+ "Celluloid::Proxy::Cell"
296
+ end
284
297
 
285
298
  str << "(#{self.class}:0x#{object_id.to_s(16)})"
286
299
  str << " " unless instance_variables.empty?
@@ -308,9 +321,10 @@ module Celluloid
308
321
  cause = case cause
309
322
  when String then RuntimeError.new(cause)
310
323
  when Exception then cause
311
- else fail TypeError, "Exception object/String expected, but #{cause.class} received"
312
- end
313
- fail AbortError.new(cause)
324
+ else raise TypeError, "Exception object/String expected, but #{cause.class} received"
325
+ end
326
+
327
+ raise AbortError, cause
314
328
  end
315
329
 
316
330
  # Terminate this actor
@@ -447,14 +461,13 @@ module Celluloid
447
461
  end
448
462
  end
449
463
 
450
- if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
451
- fail "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
452
- end
453
-
454
464
  require "celluloid/exceptions"
455
465
 
456
466
  Celluloid.logger = Logger.new(STDERR).tap do |logger|
467
+ # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
468
+ # rubocop:disable Style/GlobalVars
457
469
  logger.level = Logger::INFO unless $CELLULOID_DEBUG
470
+ # rubocop:enable Style/GlobalVars
458
471
  end
459
472
 
460
473
  Celluloid.shutdown_timeout = 10
@@ -473,8 +486,6 @@ require "celluloid/proxies"
473
486
  require "celluloid/mailbox"
474
487
  require "celluloid/mailbox/evented"
475
488
 
476
- require "celluloid/essentials"
477
-
478
489
  require "celluloid/group"
479
490
  require "celluloid/group/spawner"
480
491
  require "celluloid/group/pool" # TODO: Find way to only load this if being used.
@@ -487,13 +498,27 @@ require "celluloid/actor"
487
498
  require "celluloid/cell"
488
499
  require "celluloid/future"
489
500
 
501
+ require "celluloid/internals/call_chain"
502
+ require "celluloid/internals/cpu_counter"
503
+ require "celluloid/internals/handlers"
504
+ require "celluloid/internals/links"
505
+ require "celluloid/internals/logger"
506
+ require "celluloid/internals/method"
507
+ require "celluloid/internals/properties"
508
+ require "celluloid/internals/receivers"
509
+ require "celluloid/internals/registry"
510
+ require "celluloid/internals/responses"
511
+ require "celluloid/internals/signals"
512
+ require "celluloid/internals/stack"
513
+ require "celluloid/internals/task_set"
514
+ require "celluloid/internals/thread_handle"
515
+ require "celluloid/internals/uuid"
516
+
517
+ require "celluloid/notifications"
518
+ require "celluloid/supervision"
519
+
520
+ require "celluloid/logging"
490
521
  require "celluloid/actor/system"
491
- require "celluloid/actor/manager"
492
-
493
- require "celluloid/deprecate" unless $CELLULOID_BACKPORTED == false
494
-
495
- $CELLULOID_MONITORING = false
496
- Celluloid::Notices.output
497
522
 
498
523
  # Configure default systemwide settings
499
524