celluloid 0.17.4 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +300 -81
  3. data/CONDUCT.md +13 -0
  4. data/CONTRIBUTING.md +39 -0
  5. data/README.md +54 -155
  6. data/REFACTOR.md +1 -0
  7. data/architecture.md +120 -0
  8. data/examples/basic_usage.rb +1 -1
  9. data/examples/configurations.rb +78 -0
  10. data/examples/futures.rb +1 -1
  11. data/examples/ring.rb +5 -4
  12. data/examples/simple_pmap.rb +1 -1
  13. data/examples/stack.rb +2 -2
  14. data/examples/supervisors_and_registry.rb +82 -0
  15. data/examples/timers.rb +2 -2
  16. data/lib/celluloid/actor/system.rb +13 -29
  17. data/lib/celluloid/actor.rb +27 -17
  18. data/lib/celluloid/autostart.rb +6 -1
  19. data/lib/celluloid/call/async.rb +2 -0
  20. data/lib/celluloid/call/sync.rb +10 -3
  21. data/lib/celluloid/calls.rb +13 -12
  22. data/lib/celluloid/cell.rb +5 -9
  23. data/lib/celluloid/condition.rb +3 -3
  24. data/lib/celluloid/core_ext.rb +0 -2
  25. data/lib/celluloid/debug.rb +3 -0
  26. data/lib/celluloid/exceptions.rb +2 -2
  27. data/lib/celluloid/future.rb +8 -10
  28. data/lib/celluloid/group/pool.rb +1 -3
  29. data/lib/celluloid/group/spawner.rb +2 -6
  30. data/lib/celluloid/group.rb +12 -8
  31. data/lib/celluloid/internals/call_chain.rb +15 -0
  32. data/lib/celluloid/internals/cpu_counter.rb +62 -0
  33. data/lib/celluloid/internals/handlers.rb +42 -0
  34. data/lib/celluloid/internals/links.rb +38 -0
  35. data/lib/celluloid/internals/logger.rb +104 -0
  36. data/lib/celluloid/internals/method.rb +34 -0
  37. data/lib/celluloid/internals/properties.rb +32 -0
  38. data/lib/celluloid/internals/receivers.rb +64 -0
  39. data/lib/celluloid/internals/registry.rb +102 -0
  40. data/lib/celluloid/internals/responses.rb +46 -0
  41. data/lib/celluloid/internals/signals.rb +24 -0
  42. data/lib/celluloid/internals/stack/dump.rb +12 -0
  43. data/lib/celluloid/internals/stack/states.rb +72 -0
  44. data/lib/celluloid/internals/stack/summary.rb +12 -0
  45. data/lib/celluloid/internals/stack.rb +74 -0
  46. data/lib/celluloid/internals/task_set.rb +51 -0
  47. data/lib/celluloid/internals/thread_handle.rb +52 -0
  48. data/lib/celluloid/internals/uuid.rb +40 -0
  49. data/lib/celluloid/logging/incident.rb +21 -0
  50. data/lib/celluloid/logging/incident_logger.rb +147 -0
  51. data/lib/celluloid/logging/incident_reporter.rb +49 -0
  52. data/lib/celluloid/logging/log_event.rb +20 -0
  53. data/lib/celluloid/logging/ring_buffer.rb +64 -0
  54. data/lib/celluloid/mailbox/evented.rb +13 -5
  55. data/lib/celluloid/mailbox.rb +22 -9
  56. data/lib/celluloid/notifications.rb +95 -0
  57. data/lib/celluloid/pool.rb +6 -0
  58. data/lib/celluloid/probe.rb +81 -0
  59. data/lib/celluloid/proxy/abstract.rb +9 -9
  60. data/lib/celluloid/proxy/async.rb +1 -1
  61. data/lib/celluloid/proxy/block.rb +2 -2
  62. data/lib/celluloid/proxy/cell.rb +1 -1
  63. data/lib/celluloid/proxy/future.rb +2 -4
  64. data/lib/celluloid/proxy/sync.rb +1 -3
  65. data/lib/celluloid/rspec.rb +22 -33
  66. data/lib/celluloid/supervision/configuration/injections.rb +8 -0
  67. data/lib/celluloid/supervision/configuration/instance.rb +113 -0
  68. data/lib/celluloid/supervision/configuration.rb +169 -0
  69. data/lib/celluloid/supervision/constants.rb +123 -0
  70. data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
  71. data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
  72. data/lib/celluloid/supervision/container/behavior.rb +89 -0
  73. data/lib/celluloid/supervision/container/injections.rb +8 -0
  74. data/lib/celluloid/supervision/container/instance.rb +116 -0
  75. data/lib/celluloid/supervision/container/pool.rb +210 -0
  76. data/lib/celluloid/supervision/container.rb +144 -0
  77. data/lib/celluloid/supervision/service.rb +27 -0
  78. data/lib/celluloid/supervision/supervise.rb +34 -0
  79. data/lib/celluloid/supervision/validation.rb +40 -0
  80. data/lib/celluloid/supervision/version.rb +5 -0
  81. data/lib/celluloid/supervision.rb +17 -0
  82. data/lib/celluloid/system_events.rb +11 -6
  83. data/lib/celluloid/task/fibered.rb +6 -2
  84. data/lib/celluloid/task/threaded.rb +3 -3
  85. data/lib/celluloid/task.rb +25 -12
  86. data/lib/celluloid/test.rb +5 -2
  87. data/lib/celluloid/thread.rb +0 -2
  88. data/lib/celluloid/version.rb +1 -1
  89. data/lib/celluloid.rb +74 -64
  90. data/spec/celluloid/block_spec.rb +29 -32
  91. data/spec/celluloid/calls_spec.rb +5 -15
  92. data/spec/celluloid/future_spec.rb +7 -1
  93. data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
  94. data/spec/celluloid/internals/links_spec.rb +43 -0
  95. data/spec/celluloid/internals/properties_spec.rb +40 -0
  96. data/spec/celluloid/internals/registry_spec.rb +62 -0
  97. data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
  98. data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
  99. data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
  100. data/spec/celluloid/internals/uuid_spec.rb +9 -0
  101. data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
  102. data/spec/celluloid/mailbox/evented_spec.rb +11 -22
  103. data/spec/celluloid/misc/leak_spec.rb +3 -4
  104. data/spec/celluloid/notifications_spec.rb +140 -0
  105. data/spec/celluloid/probe_spec.rb +102 -0
  106. data/spec/celluloid/proxy_spec.rb +30 -30
  107. data/spec/celluloid/supervision/behavior_spec.rb +74 -0
  108. data/spec/celluloid/supervision/configuration_spec.rb +181 -0
  109. data/spec/celluloid/supervision/container_spec.rb +72 -0
  110. data/spec/celluloid/supervision/instance_spec.rb +13 -0
  111. data/spec/celluloid/supervision/root_spec.rb +28 -0
  112. data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
  113. data/spec/celluloid/task/fibered_spec.rb +1 -3
  114. data/spec/celluloid/task/threaded_spec.rb +1 -3
  115. data/spec/shared/actor_examples.rb +58 -33
  116. data/spec/shared/group_examples.rb +2 -2
  117. data/spec/shared/mailbox_examples.rb +1 -1
  118. data/spec/shared/stack_examples.rb +87 -0
  119. data/spec/shared/task_examples.rb +2 -3
  120. data/spec/spec_helper.rb +2 -4
  121. data/spec/support/configure_rspec.rb +2 -3
  122. data/spec/support/coverage.rb +2 -4
  123. data/spec/support/crash_checking.rb +2 -2
  124. data/spec/support/examples/actor_class.rb +3 -8
  125. data/spec/support/examples/call_class.rb +2 -2
  126. data/spec/support/examples/container_class.rb +35 -0
  127. data/spec/support/examples/evented_mailbox_class.rb +1 -2
  128. data/spec/support/examples/stack_classes.rb +58 -0
  129. data/spec/support/examples/stack_methods.rb +23 -0
  130. data/spec/support/examples/subordinate_class.rb +19 -0
  131. data/spec/support/logging.rb +3 -34
  132. data/spec/support/loose_threads.rb +3 -16
  133. data/spec/support/reset_class_variables.rb +5 -1
  134. data/spec/support/stubbing.rb +1 -1
  135. metadata +91 -289
  136. data/culture/CONDUCT.md +0 -28
  137. data/culture/Gemfile +0 -9
  138. data/culture/LICENSE.txt +0 -22
  139. data/culture/README.md +0 -22
  140. data/culture/Rakefile +0 -5
  141. data/culture/SYNC.md +0 -70
  142. data/culture/celluloid-culture.gemspec +0 -18
  143. data/culture/gems/README.md +0 -39
  144. data/culture/gems/dependencies.yml +0 -85
  145. data/culture/gems/loader.rb +0 -101
  146. data/culture/rubocop/README.md +0 -38
  147. data/culture/rubocop/lint.yml +0 -8
  148. data/culture/rubocop/metrics.yml +0 -15
  149. data/culture/rubocop/perf.yml +0 -0
  150. data/culture/rubocop/rubocop.yml +0 -5
  151. data/culture/rubocop/style.yml +0 -57
  152. data/culture/spec/gems_spec.rb +0 -2
  153. data/culture/spec/spec_helper.rb +0 -0
  154. data/culture/spec/sync_spec.rb +0 -2
  155. data/culture/sync.rb +0 -56
  156. data/culture/tasks/rspec.rake +0 -5
  157. data/culture/tasks/rubocop.rake +0 -2
  158. data/lib/celluloid/actor/manager.rb +0 -7
  159. data/lib/celluloid/backported.rb +0 -2
  160. data/lib/celluloid/current.rb +0 -2
  161. data/lib/celluloid/deprecate.rb +0 -21
  162. data/lib/celluloid/fiber.rb +0 -32
  163. data/lib/celluloid/managed.rb +0 -3
  164. data/lib/celluloid/notices.rb +0 -15
  165. data/spec/deprecate/actor_system_spec.rb +0 -72
  166. data/spec/deprecate/block_spec.rb +0 -52
  167. data/spec/deprecate/calls_spec.rb +0 -39
  168. data/spec/deprecate/evented_mailbox_spec.rb +0 -34
  169. data/spec/deprecate/future_spec.rb +0 -32
  170. data/spec/deprecate/internal_pool_spec.rb +0 -4
  171. data/spec/support/env.rb +0 -21
data/README.md CHANGED
@@ -1,93 +1,45 @@
1
- ![Celluloid](https://raw.github.com/celluloid/celluloid-logos/master/celluloid/celluloid.png)
2
- =========
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
-
8
- _NOTE: This is the 0.17.x **stable** branch of Celluloid. For the 0.18.x
9
- **development** branch, please see:_
10
-
11
- https://github.com/celluloid/celluloid
12
-
13
- > "I thought of objects being like biological cells and/or individual
14
- > computers on a network, only able to communicate with messages"
15
- > _--Alan Kay, creator of Smalltalk, on the meaning of "object oriented programming"_
16
-
17
- Celluloid provides a simple and natural way to build fault-tolerant concurrent
18
- programs in Ruby. With Celluloid, you can build systems out of concurrent
19
- objects just as easily as you build sequential programs out of regular objects.
20
- Recommended for any developer, including novices, Celluloid should help ease
21
- your worries about building multithreaded Ruby programs.
22
-
23
- Much of the difficulty with building concurrent programs in Ruby arises because
24
- the object-oriented mechanisms for structuring code, such as classes and
25
- inheritance, are separate from the concurrency mechanisms, such as threads and
26
- locks. Celluloid combines these into a single structure, an active object
27
- running within a thread, called an "actor", or in Celluloid vernacular, a "cell".
28
-
29
- By combining concurrency with object oriented programming, Celluloid frees you
30
- up from worry about where to use threads and locks. Celluloid combines them
31
- together into a single concurrent object oriented programming model,
32
- encapsulating state in concurrent objects and thus avoiding many of the
33
- problems associated with multithreaded programming. Celluloid provides many
34
- features which make concurrent programming simple, easy, and fun:
35
-
36
- * __Automatic "deadlock-free" synchronization:__ Celluloid uses a concurrent
37
- object model which combines method dispatch and thread synchronization.
38
- Each actor is a concurrent object running in its own thread, and every method
39
- invocation is wrapped in a fiber that can be suspended whenever it calls
40
- out to other actors, and resumed when the response is available. This means
41
- methods which are waiting for responses from other actors, external messages,
42
- or other system events (including I/O with Celluloid::IO) can be suspended
43
- and will never block other methods that are ready to run. This won't prevent
44
- bugs in Celluloid, bugs in other thread-safe libraries you use, and even
45
- certain "dangerous" features of Celluloid from causing your program to
46
- deadlock, but in general, programs built with Celluloid will be naturally
47
- immune to deadlocks.
48
-
49
- * __Fault-tolerance:__ Celluloid has taken to heart many of Erlang's ideas
50
- about fault-tolerance in order to enable self-healing applications.
51
- The central idea: have you tried turning it off and on again? Celluloid
52
- takes care of rebooting subcomponents of your application when they crash,
53
- whether it's a single actor, or large (potentially multi-tiered) groups of
54
- actors that are all interdependent. This means rather than worrying about
55
- rescuing every last exception, you can just sit back, relax, and let parts
56
- of your program crash, knowing Celluloid will automatically reboot them in
57
- a clean state. Celluloid provides its own implementation of the core
58
- fault-tolerance concepts in Erlang including [linking](https://github.com/celluloid/celluloid/wiki/Linking),
59
- [supervisors](https://github.com/celluloid/celluloid/wiki/Supervisors),
60
- and [supervision groups](https://github.com/celluloid/celluloid/wiki/Supervision-Groups).
61
-
62
- * __[Futures](https://github.com/celluloid/celluloid/wiki/futures):__
63
- Ever wanted to call a method "in the background" and retrieve the
64
- value it returns later? Celluloid futures do just that. It's like
65
- calling ahead to a restaurant to place an order, so they can work
66
- on preparing your food while you're on your way to pick it up.
67
- When you ask for a method's return value, it's returned immediately
68
- if the method has already completed, or otherwise the current method is
69
- suspended until the value becomes available.
70
-
71
- You can also build distributed systems with Celluloid using its
72
- [sister project DCell](https://github.com/celluloid/dcell). Evented IO similar
73
- to EventMachine (with a synchronous API instead of callback/deferrable soup)
74
- is available through the [Celluloid::IO](https://github.com/celluloid/celluloid-io)
75
- library.
76
-
77
- Like Celluloid? [Join the mailing list/Google Group](http://groups.google.com/group/celluloid-ruby)
78
- or visit us on IRC at #celluloid on freenode
79
-
80
- ### Is it any good?
81
-
82
- [Yes](http://news.ycombinator.com/item?id=3067434)
83
-
84
- ### Is It "Production Ready™"?
85
-
86
- Yes, many users are now running Celluloid in production by using
87
- [Sidekiq](http://sidekiq.org) and [Adhearsion](http://adhearsion.com/)
88
-
89
- Documentation
90
- -------------
1
+ # ![Celluloid][celluloid-logo-image-raw]
2
+
3
+ [![Gem Version][gem-image]][gem-link]
4
+ [![MIT licensed][license-image]][license-link]
5
+ [![Build Status][build-image]][build-link]
6
+ [![Maintained: no][maintained-image]][maintained-link]
7
+ [![Gitter Chat][gitter-image]][gitter-link]
8
+
9
+ [celluloid-logo-image-raw]: https://raw.github.com/celluloid/celluloid-logos/master/celluloid/celluloid.png
10
+ [gem-image]: https://badge.fury.io/rb/celluloid.svg
11
+ [gem-link]: http://rubygems.org/gems/celluloid
12
+ [build-image]: https://secure.travis-ci.org/celluloid/celluloid.svg?branch=master
13
+ [build-link]: http://travis-ci.org/celluloid/celluloid
14
+ [license-image]: https://img.shields.io/badge/license-MIT-blue.svg
15
+ [license-link]: https://github.com/celluloid/celluloid/blob/master/LICENSE.txt
16
+ [maintained-image]: https://img.shields.io/maintenance/no/2016.svg
17
+ [maintained-link]: https://github.com/celluloid/celluloid/issues/779
18
+ [gitter-image]: https://badges.gitter.im/badge.svg
19
+ [gitter-link]: https://gitter.im/celluloid/celluloid
20
+
21
+ Celluloid is a framework for building asynchronous and multithreaded Ruby
22
+ programs using object-oriented concepts.
23
+
24
+ ## Revival Process Underway
25
+
26
+ `Celluloid` is in the process of being refactored and released back into the wild during `Google Summer of Code`. The next era will not have one individual active maintainer, but a team of collaborators. Going forward, previously dormant maintainer [Donovan Keme](https://github.com/digitalextremist) is returning to support future primary maintainer [Emese Padányi](https://github.com/emesepadanyi) during `GSoC 2020`. Her plan extends past the Summer program, and aims to revive the community and codebase of `Celluloid` together. Backing this process are [Harsh Deep](https://github.com/harsh183) and `GSoC` alumni [Dilum Navanjana](https://github.com/dilumn). We welcome your collaboration and contributions in this massive work.
27
+
28
+ The codebase is being refactored to pursue a stable release with no deprecation warnings, and with this cleaned up:
29
+
30
+ # ![Diagram][celluloid-diagram]
31
+ *Diagram meticulously developed by [Emese Padányi](https://github.com/emesepadanyi)*
32
+
33
+ [celluloid-diagram]: https://raw.githubusercontent.com/celluloid/celluloid/master/documentation/ClassDiagram-class_diagram.png
34
+
35
+ ### Proudly supported by the best cloud infrastructure provider in the world: [`DigitalOcean`](https://digitalocean.com)
36
+
37
+ ## Discussion
38
+
39
+ - [Gitter Chat][gitter-link]
40
+ - [Google Group](https://groups.google.com/group/celluloid-ruby)
41
+
42
+ ## Documentation
91
43
 
92
44
  [Please see the Celluloid Wiki](https://github.com/celluloid/celluloid/wiki)
93
45
  for more detailed documentation and usage notes.
@@ -99,11 +51,9 @@ The following API documentation is also available:
99
51
  * [Celluloid class methods](http://rubydoc.info/gems/celluloid/Celluloid/ClassMethods)
100
52
  * [All Celluloid classes](http://rubydoc.info/gems/celluloid/index)
101
53
 
102
- Related Projects
103
- ----------------
54
+ ## Related Projects
104
55
 
105
- Celluloid is the parent project of a related ecosystem of other projects. If you
106
- like Celluloid we definitely recommend you check them out:
56
+ See also: [Projects Using Celluloid](https://github.com/celluloid/celluloid/wiki/Projects-Using-Celluloid)
107
57
 
108
58
  * [Reel][reel]: An "evented" web server based on `Celluloid::IO`
109
59
  * [DCell][dcell]: The Celluloid actor protocol distributed over 0MQ
@@ -112,79 +62,28 @@ like Celluloid we definitely recommend you check them out:
112
62
  * [Celluloid::ZMQ][celluloid-zmq]: "Evented" 0MQ support for `Celluloid` actors
113
63
  * [Celluloid::DNS][celluloid-dns]: An "evented" DNS server based on `Celluloid::IO`
114
64
  * [Celluloid::SMTP][celluloid-smtp]: An "evented" SMTP server based on `Celluloid::IO`
115
- * [Lattice][lattice]: A concurrent realtime web framework based on `Celluloid::IO`
116
65
  * [nio4r][nio4r]: "New IO for Ruby": high performance IO selectors
117
66
  * [Timers][timers]: A generic Ruby timer library for event-based systems
118
67
 
119
68
  [reel]: https://github.com/celluloid/reel/
120
69
  [dcell]: https://github.com/celluloid/dcell/
121
- [ecell]: https://github.com/celluloid/ecell/
70
+ [ecell]: https://github.com/abstractive/ecell/
122
71
  [celluloid-io]: https://github.com/celluloid/celluloid-io/
123
72
  [celluloid-zmq]: https://github.com/celluloid/celluloid-zmq/
124
73
  [celluloid-dns]: https://github.com/celluloid/celluloid-dns/
125
- [celluloid-smtp]: https://github.com/celluloid/celluloid-smtp/
126
- [lattice]: https://github.com/celluloid/lattice/
74
+ [celluloid-smtp]: https://github.com/abstractive/celluloid-smtp/
127
75
  [nio4r]: https://github.com/celluloid/nio4r/
128
76
  [timers]: https://github.com/celluloid/timers/
129
77
 
130
- Installation
131
- ------------
132
-
133
- Add this line to your application's Gemfile:
134
-
135
- ```ruby
136
- gem 'celluloid'
137
- ```
138
-
139
- And then execute:
140
-
141
- $ bundle
142
-
143
- Or install it yourself as:
144
-
145
- $ gem install celluloid
146
-
147
- Inside of your Ruby program, require Celluloid with [newest API](https://github.com/celluloid/celluloid/wiki/DEPRECATION-WARNING):
148
-
149
- ```ruby
150
- require 'celluloid/current'
151
- ```
152
-
153
- Or to support the old API, use:
154
-
155
- ```ruby
156
- require 'celluloid/backported'
157
- ```
158
-
159
- Supported Platforms
160
- -------------------
161
-
162
- Celluloid works on Ruby 2.0+, JRuby 1.7+, and Rubinius 2.0.
163
-
164
- JRuby or Rubinius are the preferred platforms as they support true thread-level
165
- parallelism when executing Ruby code, whereas MRI/YARV is constrained by a global
166
- interpreter lock (GIL) and can only execute one thread at a time.
167
-
168
- Celluloid requires Ruby 1.9 mode on all interpreters.
169
-
170
- Additional Reading
171
- ------------------
172
-
173
- * [Concurrent Object-Oriented Programming in Python with
174
- ATOM](http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=11A3EACE78AAFF6D6D62A64118AFCA7C?doi=10.1.1.47.5074&rep=rep1&type=pdf):
175
- a similar system to Celluloid written in Python
176
-
177
- Contributing to Celluloid
178
- -------------------------
78
+ ## Contributing to Celluloid
179
79
 
180
- * Fork this repository on github
181
- * Make your changes and send us a pull request
182
- * If we like them we'll merge them
183
- * If we've accepted a patch, feel free to ask for commit access
80
+ - Fork this repository on github
81
+ - Make your changes and send us a pull request
82
+ - Pull requests will be reviewed for inclusion in the project
184
83
 
185
- License
186
- -------
84
+ ## License
187
85
 
188
- Copyright (c) 2011-2015 Tony Arcieri, Donovan Keme.
86
+ Copyright (c) 2011-2018 Tony Arcieri, Donovan Keme.
189
87
 
190
- Distributed under the MIT License. See [LICENSE.txt](https://github.com/celluloid/celluloid/blob/master/LICENSE.txt) for further details.
88
+ Distributed under the MIT License. See [LICENSE.txt](https://github.com/celluloid/celluloid/blob/master/LICENSE.txt)
89
+ for further details.
data/REFACTOR.md ADDED
@@ -0,0 +1 @@
1
+ 20200703113000: `require "celluloid/current"` is removed. use `require "celluloid"`
data/architecture.md ADDED
@@ -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"
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!"
data/examples/futures.rb CHANGED
@@ -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
 
data/examples/ring.rb CHANGED
@@ -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
data/examples/stack.rb CHANGED
@@ -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
data/examples/timers.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
- require "celluloid/current"
3
+ $LOAD_PATH.push File.expand_path("../lib", __dir__)
4
+ require "celluloid"
5
5
 
6
6
  class TimerExample
7
7
  include Celluloid