celluloid 0.17.4 → 0.18.0

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 (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
@@ -0,0 +1,58 @@
1
+ class StackWaiter
2
+ QUEUE = Queue.new
3
+ WAITERS = Queue.new
4
+ ACTORS = Queue.new
5
+
6
+ class << self
7
+ def forever
8
+ WAITERS << Thread.current
9
+ # de QUEUE.pop
10
+ sleep
11
+ end
12
+
13
+ def no_longer
14
+ StackWaiter::ACTORS.pop.terminate until StackWaiter::ACTORS.empty?
15
+
16
+ loop do
17
+ break if WAITERS.empty?
18
+ QUEUE << nil
19
+ nicely_end_thread(WAITERS.pop)
20
+ end
21
+ end
22
+
23
+ def nicely_end_thread(th)
24
+ return if jruby_fiber?(th)
25
+
26
+ status = th.status
27
+ case status
28
+ when nil, false, "dead"
29
+ when "aborting"
30
+ th.join(2) || STDERR.puts("Thread join timed out...")
31
+ when "sleep", "run"
32
+ th.kill
33
+ th.join(2) || STDERR.puts("Thread join timed out...")
34
+ else
35
+ STDERR.puts "unknown status: #{th.status.inspect}"
36
+ end
37
+ end
38
+
39
+ def jruby_fiber?(th)
40
+ return false unless RUBY_PLATFORM == "java" && (java_th = th.to_java.getNativeThread)
41
+ /Fiber/ =~ java_th.get_name
42
+ end
43
+ end
44
+ end
45
+
46
+ class StackBlocker
47
+ include Celluloid
48
+
49
+ def initialize(threads)
50
+ @threads = threads
51
+ end
52
+
53
+ def blocking
54
+ StackWaiter::ACTORS << Thread.current
55
+ @threads << Thread.current
56
+ StackWaiter.forever
57
+ end
58
+ end
@@ -0,0 +1,23 @@
1
+ def create_async_blocking_actor(task_klass)
2
+ actor_klass = Class.new(StackBlocker) do
3
+ task_class task_klass
4
+ end
5
+
6
+ actor = actor_system.within do
7
+ actor_klass.new(threads)
8
+ end
9
+
10
+ actor.async.blocking
11
+ end
12
+
13
+ def create_thread_with_role(threads, role)
14
+ resume = Queue.new
15
+ thread = actor_system.get_thread do
16
+ resume.pop # to avoid race for 'thread' variable
17
+ thread.role = role
18
+ threads << thread
19
+ StackWaiter.forever
20
+ end
21
+ resume << nil # to avoid race for 'thread' variable
22
+ thread
23
+ end
@@ -0,0 +1,19 @@
1
+ class SubordinateDead < Celluloid::Error; end
2
+
3
+ class Subordinate
4
+ include Celluloid
5
+ attr_reader :state
6
+
7
+ def initialize(state)
8
+ @state = state
9
+ end
10
+
11
+ def crack_the_whip
12
+ case @state
13
+ when :idle
14
+ @state = :working
15
+ else
16
+ raise SubordinateDead, "the spec purposely crashed me :("
17
+ end
18
+ end
19
+ end
@@ -1,21 +1,7 @@
1
1
  module Specs
2
2
  class << self
3
- def log
4
- # Setup ENV variable handling with sane defaults
5
- @log ||= Nenv("celluloid_specs_log") do |env|
6
- env.create_method(:file) { |f| f || "log/default.log" }
7
- env.create_method(:sync?) { |s| s || !Nenv.ci? }
8
-
9
- env.create_method(:strategy) do |strategy|
10
- strategy || default_strategy
11
- end
12
-
13
- env.create_method(:level) { |level| default_level_for(env, level) }
14
- end
15
- end
16
-
17
3
  def logger
18
- @logger ||= default_logger.tap { |logger| logger.level = log.level }
4
+ @logger ||= default_logger.tap { |log| log.level = Logger::WARN }
19
5
  end
20
6
 
21
7
  attr_writer :logger
@@ -23,33 +9,16 @@ module Specs
23
9
  private
24
10
 
25
11
  def default_logger
26
- case log.strategy
27
- when "stderr"
28
- Logger.new(STDERR)
29
- when "single"
30
- Logger.new(open_logfile(log.file, log.sync?))
31
- else
32
- fail "Unknown logger strategy: #{strategy.inspect}."\
33
- " Expected 'single' or 'stderr'."
34
- end
12
+ Logger.new(STDERR)
35
13
  end
36
14
 
37
15
  def open_logfile(rel_path, sync)
38
16
  root = Pathname(__FILE__).dirname.dirname.dirname
39
17
  log_path = root + rel_path
18
+ log_path.dirname.mkpath
40
19
  logfile = File.open(log_path.to_s, "a")
41
20
  logfile.sync if sync
42
21
  logfile
43
22
  end
44
-
45
- def default_strategy
46
- (Nenv.ci? ? "stderr" : "single")
47
- end
48
-
49
- def default_level_for(env, level)
50
- Integer(level)
51
- rescue
52
- env.strategy == "stderr" ? Logger::WARN : Logger::DEBUG
53
- end
54
23
  end
55
24
  end
@@ -13,20 +13,7 @@ module Specs
13
13
  backtrace = thread.backtrace # avoid race maybe
14
14
  next unless backtrace
15
15
  next if backtrace.empty? # possibly a timer thread
16
- end
17
-
18
- if RUBY_ENGINE == "rbx"
19
- # Avoid disrupting Rubinious thread
20
- next if thread.backtrace.first =~ %r{rubysl/timeout/timeout\.rb}
21
-
22
- if Specs::ALLOW_SLOW_MAILBOXES
23
- if thread.backtrace.first =~ /wait/
24
- next if thread.backtrace[1] =~ /mailbox\.rb/ && thread.backtrace[1] =~ /check/
25
- end
26
- end
27
- end
28
-
29
- if RUBY_ENGINE == "ruby"
16
+ else
30
17
  # Sometimes stays
31
18
  next if thread.backtrace.nil?
32
19
  next unless thread.backtrace.is_a?(Array)
@@ -39,7 +26,7 @@ module Specs
39
26
  end
40
27
 
41
28
  def thread_name(thread)
42
- (RUBY_PLATFORM == "java") ? thread.to_java.getNativeThread.get_name : ""
29
+ RUBY_PLATFORM == "java" ? thread.to_java.getNativeThread.get_name : ""
43
30
  end
44
31
 
45
32
  def assert_no_loose_threads!(location)
@@ -61,7 +48,7 @@ module Specs
61
48
  sleep
62
49
  end
63
50
 
64
- fail Celluloid::ThreadLeak, "Aborted due to runaway threads (#{location})\n"\
51
+ raise Celluloid::ThreadLeak, "Aborted due to runaway threads (#{location})\n"\
65
52
  "List: (#{loose.map(&:inspect)})\n:#{backtraces.join("\n")}"
66
53
  end
67
54
  end
@@ -2,7 +2,7 @@ module Specs
2
2
  class << self
3
3
  def reset_class_variables(description)
4
4
  # build uuid from example ending (most unique)
5
- uuid_prefix = description[-([description.size, 20].min)..-1]
5
+ uuid_prefix = description[-[description.size, 20].min..-1]
6
6
  reset_uuid(uuid_prefix)
7
7
 
8
8
  reset_probe(Queue.new)
@@ -11,7 +11,11 @@ module Specs
11
11
  end
12
12
 
13
13
  def reset_probe(value)
14
+ # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
15
+ # rubocop:disable Style/GlobalVars
14
16
  $CELLULOID_MONITORING = !value.nil?
17
+ # rubocop:enable Style/GlobalVars
18
+
15
19
  replace_const(Celluloid::Probe, :EVENTS_BUFFER, value)
16
20
  end
17
21
 
@@ -3,7 +3,7 @@ module Specs
3
3
  meta = (class << mod; self; end)
4
4
  original_meth = "original_#{meth}".to_sym
5
5
 
6
- fail "ALREADY TRACED: #{mod}.#{meth}" if mod.respond_to?(original_meth)
6
+ raise "ALREADY TRACED: #{mod}.#{meth}" if mod.respond_to?(original_meth)
7
7
 
8
8
  meta.send(:alias_method, original_meth, meth)
9
9
  meta.send(:define_method, meth) do |*args, &block|