celluloid 0.16.0 → 0.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +394 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +28 -15
  5. data/culture/CONDUCT.md +28 -0
  6. data/culture/Gemfile +9 -0
  7. data/culture/LICENSE.txt +22 -0
  8. data/culture/README.md +22 -0
  9. data/culture/Rakefile +5 -0
  10. data/culture/SYNC.md +70 -0
  11. data/culture/celluloid-culture.gemspec +18 -0
  12. data/culture/gems/README.md +39 -0
  13. data/culture/gems/dependencies.yml +85 -0
  14. data/culture/gems/loader.rb +101 -0
  15. data/culture/rubocop/README.md +38 -0
  16. data/culture/rubocop/lint.yml +8 -0
  17. data/culture/rubocop/metrics.yml +15 -0
  18. data/culture/rubocop/perf.yml +0 -0
  19. data/culture/rubocop/rubocop.yml +5 -0
  20. data/culture/rubocop/style.yml +57 -0
  21. data/culture/spec/gems_spec.rb +2 -0
  22. data/culture/spec/spec_helper.rb +0 -0
  23. data/culture/spec/sync_spec.rb +2 -0
  24. data/culture/sync.rb +56 -0
  25. data/culture/tasks/rspec.rake +5 -0
  26. data/culture/tasks/rubocop.rake +2 -0
  27. data/examples/basic_usage.rb +49 -0
  28. data/examples/futures.rb +38 -0
  29. data/examples/ring.rb +61 -0
  30. data/examples/simple_pmap.rb +14 -0
  31. data/examples/stack.rb +47 -0
  32. data/examples/timers.rb +72 -0
  33. data/lib/celluloid/actor/manager.rb +7 -0
  34. data/lib/celluloid/actor/system.rb +163 -0
  35. data/lib/celluloid/actor.rb +53 -71
  36. data/lib/celluloid/autostart.rb +1 -1
  37. data/lib/celluloid/backported.rb +2 -0
  38. data/lib/celluloid/call/async.rb +16 -0
  39. data/lib/celluloid/call/block.rb +22 -0
  40. data/lib/celluloid/call/sync.rb +70 -0
  41. data/lib/celluloid/calls.rb +24 -114
  42. data/lib/celluloid/cell.rb +32 -20
  43. data/lib/celluloid/condition.rb +5 -6
  44. data/lib/celluloid/core_ext.rb +1 -1
  45. data/lib/celluloid/current.rb +2 -0
  46. data/lib/celluloid/debug.rb +1 -0
  47. data/lib/celluloid/deprecate.rb +21 -0
  48. data/lib/celluloid/exceptions.rb +22 -16
  49. data/lib/celluloid/fiber.rb +3 -3
  50. data/lib/celluloid/future.rb +46 -8
  51. data/lib/celluloid/group/pool.rb +125 -0
  52. data/lib/celluloid/group/spawner.rb +68 -0
  53. data/lib/celluloid/group.rb +61 -0
  54. data/lib/celluloid/logging.rb +5 -5
  55. data/lib/celluloid/mailbox/evented.rb +74 -0
  56. data/lib/celluloid/mailbox.rb +15 -14
  57. data/lib/celluloid/managed.rb +3 -0
  58. data/lib/celluloid/notices.rb +15 -0
  59. data/lib/celluloid/proxies.rb +11 -0
  60. data/lib/celluloid/proxy/abstract.rb +50 -0
  61. data/lib/celluloid/proxy/actor.rb +37 -0
  62. data/lib/celluloid/proxy/async.rb +15 -0
  63. data/lib/celluloid/proxy/block.rb +28 -0
  64. data/lib/celluloid/proxy/cell.rb +66 -0
  65. data/lib/celluloid/proxy/future.rb +20 -0
  66. data/lib/celluloid/proxy/sync.rb +24 -0
  67. data/lib/celluloid/rspec.rb +67 -9
  68. data/lib/celluloid/system_events.rb +69 -14
  69. data/lib/celluloid/task/fibered.rb +45 -0
  70. data/lib/celluloid/task/threaded.rb +59 -0
  71. data/lib/celluloid/{tasks.rb → task.rb} +30 -38
  72. data/lib/celluloid/test.rb +1 -1
  73. data/lib/celluloid/thread.rb +6 -1
  74. data/lib/celluloid/version.rb +3 -0
  75. data/lib/celluloid.rb +151 -130
  76. data/spec/celluloid/actor/system_spec.rb +83 -0
  77. data/spec/celluloid/actor_spec.rb +2 -2
  78. data/spec/celluloid/block_spec.rb +67 -8
  79. data/spec/celluloid/calls_spec.rb +28 -23
  80. data/spec/celluloid/condition_spec.rb +23 -14
  81. data/spec/celluloid/evented_mailbox_spec.rb +1 -31
  82. data/spec/celluloid/future_spec.rb +15 -12
  83. data/spec/celluloid/group/elastic_spec.rb +0 -0
  84. data/spec/celluloid/group/pool_spec.rb +8 -0
  85. data/spec/celluloid/group/spawner_spec.rb +17 -0
  86. data/spec/celluloid/mailbox/evented_spec.rb +40 -0
  87. data/spec/celluloid/mailbox_spec.rb +1 -3
  88. data/spec/celluloid/misc/leak_spec.rb +73 -0
  89. data/spec/celluloid/proxy_spec.rb +33 -0
  90. data/spec/celluloid/task/fibered_spec.rb +5 -0
  91. data/spec/celluloid/task/threaded_spec.rb +5 -0
  92. data/spec/celluloid/timer_spec.rb +14 -16
  93. data/spec/deprecate/actor_system_spec.rb +72 -0
  94. data/spec/deprecate/block_spec.rb +52 -0
  95. data/spec/deprecate/calls_spec.rb +39 -0
  96. data/spec/deprecate/evented_mailbox_spec.rb +34 -0
  97. data/spec/deprecate/future_spec.rb +32 -0
  98. data/spec/deprecate/internal_pool_spec.rb +4 -0
  99. data/spec/shared/actor_examples.rb +1259 -0
  100. data/spec/shared/group_examples.rb +121 -0
  101. data/spec/shared/mailbox_examples.rb +87 -0
  102. data/{lib/celluloid/rspec → spec/shared}/task_examples.rb +9 -8
  103. data/spec/spec_helper.rb +5 -42
  104. data/spec/support/configure_rspec.rb +77 -0
  105. data/spec/support/coverage.rb +4 -0
  106. data/spec/support/crash_checking.rb +68 -0
  107. data/spec/support/debugging.rb +31 -0
  108. data/spec/support/env.rb +21 -0
  109. data/{lib/celluloid/rspec/example_actor_class.rb → spec/support/examples/actor_class.rb} +21 -2
  110. data/spec/support/examples/call_class.rb +37 -0
  111. data/spec/support/examples/evented_mailbox_class.rb +27 -0
  112. data/spec/support/includer.rb +6 -0
  113. data/spec/support/logging.rb +55 -0
  114. data/spec/support/loose_threads.rb +68 -0
  115. data/spec/support/reset_class_variables.rb +27 -0
  116. data/spec/support/sleep_and_wait.rb +14 -0
  117. data/spec/support/stubbing.rb +14 -0
  118. metadata +276 -78
  119. data/lib/celluloid/actor_system.rb +0 -107
  120. data/lib/celluloid/call_chain.rb +0 -13
  121. data/lib/celluloid/cpu_counter.rb +0 -34
  122. data/lib/celluloid/evented_mailbox.rb +0 -73
  123. data/lib/celluloid/fsm.rb +0 -186
  124. data/lib/celluloid/handlers.rb +0 -41
  125. data/lib/celluloid/internal_pool.rb +0 -159
  126. data/lib/celluloid/legacy.rb +0 -9
  127. data/lib/celluloid/links.rb +0 -36
  128. data/lib/celluloid/logger.rb +0 -93
  129. data/lib/celluloid/logging/incident.rb +0 -21
  130. data/lib/celluloid/logging/incident_logger.rb +0 -129
  131. data/lib/celluloid/logging/incident_reporter.rb +0 -48
  132. data/lib/celluloid/logging/log_event.rb +0 -20
  133. data/lib/celluloid/logging/ring_buffer.rb +0 -65
  134. data/lib/celluloid/method.rb +0 -32
  135. data/lib/celluloid/notifications.rb +0 -83
  136. data/lib/celluloid/pool_manager.rb +0 -146
  137. data/lib/celluloid/probe.rb +0 -73
  138. data/lib/celluloid/properties.rb +0 -24
  139. data/lib/celluloid/proxies/abstract_proxy.rb +0 -20
  140. data/lib/celluloid/proxies/actor_proxy.rb +0 -38
  141. data/lib/celluloid/proxies/async_proxy.rb +0 -31
  142. data/lib/celluloid/proxies/block_proxy.rb +0 -29
  143. data/lib/celluloid/proxies/cell_proxy.rb +0 -68
  144. data/lib/celluloid/proxies/future_proxy.rb +0 -35
  145. data/lib/celluloid/proxies/sync_proxy.rb +0 -36
  146. data/lib/celluloid/receivers.rb +0 -63
  147. data/lib/celluloid/registry.rb +0 -57
  148. data/lib/celluloid/responses.rb +0 -44
  149. data/lib/celluloid/rspec/actor_examples.rb +0 -1054
  150. data/lib/celluloid/rspec/mailbox_examples.rb +0 -84
  151. data/lib/celluloid/signals.rb +0 -23
  152. data/lib/celluloid/stack_dump.rb +0 -133
  153. data/lib/celluloid/supervision_group.rb +0 -169
  154. data/lib/celluloid/supervisor.rb +0 -22
  155. data/lib/celluloid/task_set.rb +0 -49
  156. data/lib/celluloid/tasks/task_fiber.rb +0 -43
  157. data/lib/celluloid/tasks/task_thread.rb +0 -53
  158. data/lib/celluloid/thread_handle.rb +0 -50
  159. data/lib/celluloid/uuid.rb +0 -38
  160. data/spec/celluloid/actor_system_spec.rb +0 -69
  161. data/spec/celluloid/cpu_counter_spec.rb +0 -82
  162. data/spec/celluloid/fsm_spec.rb +0 -107
  163. data/spec/celluloid/internal_pool_spec.rb +0 -52
  164. data/spec/celluloid/links_spec.rb +0 -45
  165. data/spec/celluloid/logging/ring_buffer_spec.rb +0 -38
  166. data/spec/celluloid/notifications_spec.rb +0 -120
  167. data/spec/celluloid/pool_spec.rb +0 -92
  168. data/spec/celluloid/probe_spec.rb +0 -121
  169. data/spec/celluloid/properties_spec.rb +0 -42
  170. data/spec/celluloid/registry_spec.rb +0 -64
  171. data/spec/celluloid/stack_dump_spec.rb +0 -64
  172. data/spec/celluloid/supervision_group_spec.rb +0 -65
  173. data/spec/celluloid/supervisor_spec.rb +0 -103
  174. data/spec/celluloid/tasks/task_fiber_spec.rb +0 -5
  175. data/spec/celluloid/tasks/task_thread_spec.rb +0 -5
  176. data/spec/celluloid/thread_handle_spec.rb +0 -26
  177. data/spec/celluloid/uuid_spec.rb +0 -11
@@ -0,0 +1,39 @@
1
+ # Motivation
2
+ To achieve the higher level of modularity, Celluloid was split into small sub-projects that naturally depend on each other.
3
+ Bundler can't handle circular dependencies properly and currently the only workaround is to list all celluloid-ish dependencies in both Gemfile and gemspec.
4
+ This is error-prone and not efficient. Thus it was required to put some better workaround in place.
5
+
6
+ # Configuration
7
+ The list of gems and their properties are now defined in `dependencies.yml`.
8
+
9
+ For example:
10
+
11
+ ```yml
12
+ celluloid:
13
+ bundler:
14
+ github: celluloid/celluloid
15
+ branch: 0.17.0-prerelease
16
+ celluloid-extras:
17
+ bundler:
18
+ github: celluloid/celluloid-extras
19
+ celluloid-supervision:
20
+ bundler:
21
+ github: celluloid/celluloid-supervision
22
+ celluloid-pool:
23
+ bundler:
24
+ github: celluloid/celluloid-pool
25
+ celluloid-fsm:
26
+ bundler:
27
+ github: celluloid/celluloid-fsm
28
+ timers:
29
+ gemspec:
30
+ - ~> 4.0.0
31
+ bundler:
32
+ github: celluloid/timers
33
+ ```
34
+
35
+ # Modification of `gemspec` and `Gemfile`
36
+
37
+ The injection of dependencies into `gemspec` and `Gemfile` is handled by `Celluloid::Sync.gems()`, which routes to either `Celluloid::Gems.gemspec` or `Celluloid::Gems.gemfile` depending on what is passed to it:
38
+
39
+ * Discussed in [SYNC.md](../SYNC.md#how-do-you-install-it-in-gemfile-and-gemspec-then)
@@ -0,0 +1,85 @@
1
+ bundler:
2
+ dependency: development
3
+
4
+ nenv:
5
+ dependency: development
6
+
7
+ dotenv:
8
+ dependency: development
9
+
10
+ benchmark_suite:
11
+ dependency: development
12
+
13
+ rubocop:
14
+ dependency: development
15
+
16
+ transpec:
17
+ dependency: development
18
+
19
+ pry:
20
+ dependency: development
21
+
22
+ rake:
23
+ dependency: development
24
+
25
+ rspec:
26
+ dependency: development
27
+
28
+ guard-rspec:
29
+ dependency: development
30
+
31
+ rspec-retry:
32
+ dependency: development
33
+
34
+ coveralls:
35
+ dependency: development
36
+ gemfile:
37
+ require: false
38
+
39
+ celluloid:
40
+ dependency: core
41
+ version: ">= 0.17.2"
42
+ gemfile:
43
+ github: celluloid/celluloid
44
+ branch: master
45
+ submodules: true
46
+
47
+ celluloid-essentials:
48
+ dependency: module
49
+ gemfile:
50
+ github: celluloid/celluloid-essentials
51
+ branch: master
52
+ submodules: true
53
+
54
+ celluloid-supervision:
55
+ dependency: module
56
+ gemfile:
57
+ github: celluloid/celluloid-supervision
58
+ branch: master
59
+ submodules: true
60
+
61
+ celluloid-pool:
62
+ dependency: module
63
+ gemfile:
64
+ github: celluloid/celluloid-pool
65
+ branch: master
66
+ submodules: true
67
+
68
+ celluloid-fsm:
69
+ dependency: module
70
+ gemfile:
71
+ github: celluloid/celluloid-fsm
72
+ branch: master
73
+ submodules: true
74
+
75
+ celluloid-extras:
76
+ dependency: module
77
+ gemfile:
78
+ github: celluloid/celluloid-extras
79
+ branch: master
80
+ submodules: true
81
+
82
+ timers:
83
+ version: ">= 4.1.1"
84
+ gemfile:
85
+ github: celluloid/timers
@@ -0,0 +1,101 @@
1
+ require "yaml"
2
+
3
+ module Celluloid
4
+ module Sync
5
+ module Gemfile
6
+ class << self
7
+ def [](dsl)
8
+ dsl.source("https://rubygems.org")
9
+ dsl.gemspec # Runs gemspec, but also @sets gem_name.
10
+ Gems.gemfile(dsl)
11
+ end
12
+ end
13
+ end
14
+ module Gemspec
15
+ class << self
16
+ def [](gem)
17
+ Gems.gemspec(gem)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ module Gems
23
+ extend self
24
+ @gem_name = nil
25
+
26
+ undef gems rescue nil
27
+ def gems
28
+ File.expand_path("../dependencies.yml", __FILE__)
29
+ end
30
+
31
+ unless @dependencies ||= nil
32
+ @dependencies = YAML.load_file(gems) if File.exist?(gems)
33
+ end
34
+
35
+ unless @dependencies.is_a?(Hash) && @dependencies.any?
36
+ fail "Celluloid cannot find its dependencies."
37
+ end
38
+
39
+ undef core? rescue nil
40
+ def core?(name=@gem_name)
41
+ return false unless @dependencies[name].is_a? Hash
42
+ @dependencies[name]["dependency"] == "core"
43
+ end
44
+
45
+ undef separate? rescue nil
46
+ def separate?
47
+ !@dependencies.keys.include?(@gem_name)
48
+ end
49
+
50
+ undef gemspec rescue nil
51
+ def gemspec(gem)
52
+ @gem_name = gem.name
53
+ loader do |name, spec|
54
+ # Rules for dependencies, to avoid so-called circular dependency:
55
+ # - Only the core gem lists all the modules as runtime dependencies.
56
+ # - If this gem is not in the dependencies list, then it needs the core gem at runtime;
57
+ # the module gems are development dependencies only. This is a depending separate gem.
58
+ # There is the core gem, module gems, true dependencies, and separately depending gems.
59
+ # - If the dependency is a module, it is only a development dependency to other modules,
60
+ # and even the core gem is a development dependency. It is not expected to be used alone.
61
+ meth = case spec["dependency"]
62
+ when "core", "module"
63
+ # For the core gem, all modules are runtime dependencies.
64
+ # For separate gems, only the core gem is a runtime dependency.
65
+ if core? || (separate? && core?(name))
66
+ :add_runtime_dependency
67
+ else
68
+ :add_development_dependency
69
+ end
70
+ when "development"
71
+ :add_development_dependency
72
+ else
73
+ :add_dependency
74
+ end
75
+ gem.send(meth, name, spec["version"] || ">= 0")
76
+ end
77
+ end
78
+
79
+ undef gemfile rescue nil
80
+ def gemfile(dsl)
81
+ loader do |name, spec|
82
+ params = [name, spec["version"] || ">= 0"]
83
+ req = spec["gemfile"] || {}
84
+ params << req.each_with_object({}) { |(k, v), o| o[k.to_sym] = v }
85
+ current = dsl.dependencies.find { |d| d.name == name }
86
+ dsl.dependencies.delete(current) if current
87
+ dsl.gem(*params)
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def loader
94
+ @dependencies.each do |name, spec|
95
+ next if name == @gem_name
96
+ spec ||= {}
97
+ yield name, spec
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,38 @@
1
+ # About
2
+ [RuboCop](https://github.com/bbatsov/rubocop) is a ruby static code analyzer.
3
+ It's more than just a lint. It verifies the code against ruby best practices and performs code correctness analysis.
4
+ Celluloid culture doesn't always agree with all rubocop default policies and so we provide a rubocop configuration file that overrides its default behavior.
5
+
6
+ # Integration
7
+
8
+ [Integrate `celluloid/culture`](../README.md#integration), then include `culture/rupocop/.rubocop.yml` in your default rubocop config.
9
+
10
+ ##### Add celluloid/culture as GIT submodule:
11
+
12
+ * See instructions: [Integrate the `celluloid/culture` sub-module](../README.md#integration)
13
+
14
+ ##### Include `culture/rupocop/rubocop.yml` in the `.rubocop.yml` in the root of your project:
15
+ ```yml
16
+ inherit_from:
17
+ - culture/rubocop/rubocop.yml
18
+ ```
19
+
20
+ # How to add rubocop to your project
21
+
22
+ The `rubocop` gem is automatically included by `Celluloid::Sync.gems` when that is [implemented](../SYNC.md).
23
+
24
+ ##### Add a 'rubocop' target in your `Rakefile`
25
+
26
+ # Hints
27
+ It's possible to use rubocop for autocorrection of minor problems.
28
+
29
+ Always verify these changes by running:
30
+
31
+ ```sh
32
+ bundle exec rubocop
33
+ ```
34
+
35
+ Once you are ready to auto-corret the issues you are shown, run it with the `-a` option:
36
+ ```sh
37
+ bundle exec rubocop -a
38
+ ```
@@ -0,0 +1,8 @@
1
+ Lint/HandleExceptions:
2
+ Enabled: false
3
+
4
+ Lint/LiteralInCondition:
5
+ Enabled: false
6
+
7
+ Lint/UnusedBlockArgument:
8
+ Enabled: false
@@ -0,0 +1,15 @@
1
+ Metrics/MethodLength:
2
+ CountComments: false
3
+ Max: 20
4
+
5
+ Metrics/LineLength:
6
+ Max: 120
7
+
8
+ Metrics/CyclomaticComplexity:
9
+ Max: 9
10
+
11
+ Metrics/PerceivedComplexity:
12
+ Max: 9
13
+
14
+ Metrics/AbcSize:
15
+ Max: 20
File without changes
@@ -0,0 +1,5 @@
1
+ inherit_from:
2
+ - lint.yml
3
+ - metrics.yml
4
+ - style.yml
5
+ - perf.yml
@@ -0,0 +1,57 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+
4
+ Style/ModuleFunction:
5
+ Enabled: false
6
+
7
+ Style/AndOr:
8
+ Enabled: true
9
+
10
+ Style/StringLiterals:
11
+ Enabled: true
12
+ EnforcedStyle: double_quotes
13
+
14
+ Style/EachWithObject:
15
+ Enabled: true
16
+
17
+ Style/InfiniteLoop:
18
+ Enabled: false
19
+
20
+ Style/SpaceAroundEqualsInParameterDefault:
21
+ Enabled: false
22
+
23
+ Style/SpaceInsideBlockBraces:
24
+ Enabled: false
25
+
26
+ Style/AccessModifierIndentation:
27
+ Enabled: false
28
+
29
+ Style/TrailingComma:
30
+ Enabled: true
31
+ EnforcedStyleForMultiline: comma
32
+
33
+ Style/SpaceInsideBlockBraces:
34
+ Enabled: true
35
+ EnforcedStyle: space
36
+
37
+ Style/SpaceInsideHashLiteralBraces:
38
+ Enabled: true
39
+ EnforcedStyle: no_space
40
+
41
+ Style/EmptyLinesAroundAccessModifier:
42
+ Enabled: false
43
+
44
+ Style/RescueModifier:
45
+ Enabled: false
46
+
47
+ Style/GlobalVars:
48
+ Enabled: false
49
+
50
+ Style/FormatString:
51
+ EnforcedStyle: percent
52
+
53
+ Style/TrailingUnderscoreVariable:
54
+ Enabled: false
55
+
56
+ Style/ParallelAssignment:
57
+ Enabled: false
@@ -0,0 +1,2 @@
1
+ Rspec.describe Celluloid::Gems do
2
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ Rspec.describe Celluloid::Sync do
2
+ end
data/culture/sync.rb ADDED
@@ -0,0 +1,56 @@
1
+ require "forwardable"
2
+
3
+ module Celluloid
4
+ module Sync
5
+ class << self
6
+ undef gem_path rescue nil
7
+ def gem_path
8
+ File.expand_path("../../", __FILE__)
9
+ end
10
+
11
+ undef gem_name rescue nil
12
+ def gem_name
13
+ Dir["#{File.expand_path('../../', __FILE__)}/*.gemspec"].first.gsub(".gemspec", "").split("/").last
14
+ end
15
+
16
+ undef gem_name? rescue nil
17
+ def gem_name?
18
+ !gem_name.nil?
19
+ end
20
+
21
+ undef lib_path rescue nil
22
+ def lib_path
23
+ File.expand_path("../../lib", __FILE__)
24
+ end
25
+
26
+ undef lib_gempath rescue nil
27
+ def lib_gempath
28
+ "#{lib_path}/#{gem_name.split('-').join('/')}"
29
+ end
30
+
31
+ undef scenario rescue nil
32
+ def scenario
33
+ File.basename($PROGRAM_NAME)
34
+ end
35
+
36
+ undef bundler? rescue nil
37
+ def bundler?
38
+ scenario == "bundle"
39
+ end
40
+ end
41
+
42
+ fail "Missing gemspec." unless gem_name?
43
+ $LOAD_PATH.push(gem_path)
44
+ $LOAD_PATH.push(lib_path)
45
+
46
+ # TODO: This will likely need to be done differently if INSIDE a cut gem.
47
+ if scenario == "bundle"
48
+ `cd #{gem_path}/culture; git pull origin master` if ARGV.first == "update"
49
+ end
50
+
51
+ require("#{gem_path}/culture/gems/loader")
52
+ if File.exist?(version = "#{lib_gempath}/version.rb")
53
+ require(version)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ require "rspec/core/rake_task"
2
+
3
+ RSpec::Core::RakeTask.new(:rcov) do |task|
4
+ task.rcov = true
5
+ end
@@ -0,0 +1,2 @@
1
+ require "rubocop/rake_task"
2
+ RuboCop::RakeTask.new
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ require "celluloid/autostart"
5
+
6
+ class Counter
7
+ # This is all you have to do to turn any Ruby class into one which creates
8
+ # Celluloid actors instead of normal objects
9
+ include Celluloid
10
+
11
+ # Now just define methods like you ordinarily would
12
+ attr_reader :count
13
+
14
+ def initialize
15
+ @count = 0
16
+ end
17
+
18
+ def increment(n = 1)
19
+ @count += n
20
+ end
21
+ end
22
+
23
+ # Create objects just like you normally would. 'actor' is now a proxy object
24
+ # which talks to a Celluloid actor running in its own thread
25
+ actor = Counter.new
26
+
27
+ # The proxy obeys normal method invocation the way we'd expect. This prints 0
28
+ p actor.count
29
+
30
+ # This increments @count by 1 and prints 1
31
+ p actor.increment
32
+
33
+ # By using actor.async, you can make calls asynchronously. This immediately
34
+ # requests execution of method by sending a message, and we have no idea
35
+ # whether or not that request will actually complete because we don't wait
36
+ # for a response. Async calls immediately return nil regardless of how long
37
+ # the method takes to execute. Therefore, this will print nil.
38
+ p actor.async.increment 41
39
+
40
+ # In practice, the asynchronous call made above will increment the count before
41
+ # we get here. However, do not rely on this behavior! Asynchronous methods are
42
+ # inherently uncoordinated. If you need to coordinate asynchronous activities,
43
+ # you will need to use futures or FSMs. See the corresponding examples for those.
44
+ # Signals can also be used to coordinate asynchronous activities.
45
+ #
46
+ # The following line could possibly print either 1 or 42, depending on if the
47
+ # asynchronous call above completed. In practice, it prints 42 on all Ruby
48
+ # implementations because the asynchronous call above will always execute
49
+ p actor.count
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ require "celluloid/autostart"
5
+ require "digest/sha2"
6
+
7
+ class Hasher
8
+ include Celluloid
9
+
10
+ def initialize(secret)
11
+ @hash = Digest::SHA2.hexdigest(secret)
12
+ end
13
+
14
+ # Add some data into our hash. This demonstrates a non-trivial computation
15
+ # of the same sort as, say, calculating Fibonacci numbers. Since Celluloid
16
+ # uses several threads, doing something like this won't grind our entire
17
+ # application to a halt
18
+ def add(data, n = 100_000)
19
+ string = @hash + data
20
+ n.times { string = Digest::SHA2.hexdigest(string) }
21
+ @hash = string
22
+ end
23
+ end
24
+
25
+ # Create the hasher
26
+ hasher = Hasher.new("super secret initialization data")
27
+
28
+ # Ask the hasher to perform a complex computation. However, since we're using
29
+ # a future, this doesn't block the current thread
30
+ future = hasher.future.add("some data to be hashed")
31
+
32
+ # We've kicked off the hasher, but this thread can continue performing other
33
+ # activities while the hasher runs in the background
34
+ puts "The hasher is now running, but this thread is free to do whatever it wants"
35
+
36
+ # Now let's ask for the return value from the hasher
37
+ puts "Getting the hasher's return value... "
38
+ p future.value
data/examples/ring.rb ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ require "celluloid/autostart"
5
+
6
+ class Ring
7
+ include Celluloid
8
+
9
+ class Node
10
+ include Celluloid
11
+
12
+ def initialize(link)
13
+ @link = link
14
+ end
15
+
16
+ def around(n)
17
+ @link.async.around n
18
+ end
19
+ end
20
+
21
+ def initialize(size)
22
+ @node = Node.new_link current_actor
23
+
24
+ size.times do
25
+ @node = Node.new_link @node
26
+ end
27
+ end
28
+
29
+ # Go around the ring the given number of times
30
+ def run(n)
31
+ fail ArgumentError, "I can't go around a negative number of times" if n < 0
32
+
33
+ async.around n
34
+ wait :done
35
+ end
36
+
37
+ # Go around the ring the given number of times
38
+ def around(n)
39
+ if n.zero?
40
+ signal :done
41
+ else
42
+ @node.async.around n - 1
43
+ end
44
+ end
45
+ end
46
+
47
+ if $PROGRAM_NAME == __FILE__
48
+ require "benchmark"
49
+ SIZE = 512
50
+ TIMES = 10
51
+
52
+ puts "*** Creating a #{SIZE} node ring..."
53
+ puts Benchmark.measure {
54
+ $ring = Ring.new(SIZE)
55
+ }
56
+
57
+ puts "*** Sending a message around #{TIMES} times"
58
+ puts Benchmark.measure {
59
+ $ring.run(TIMES)
60
+ }
61
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path("../../lib", __FILE__)
4
+ require "celluloid/autostart"
5
+
6
+ module Enumerable
7
+ # Simple parallel map using Celluloid::Futures
8
+ def pmap(&block)
9
+ futures = map { |elem| Celluloid::Future.new(elem, &block) }
10
+ futures.map(&:value)
11
+ end
12
+ end
13
+
14
+ p 100.times.pmap { |n| n * 2 }
data/examples/stack.rb ADDED
@@ -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