celluloid 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of celluloid might be problematic. Click here for more details.

Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +333 -0
  3. data/README.md +1 -1
  4. data/culture/CODE_OF_CONDUCT.md +28 -0
  5. data/culture/Gemfile +9 -0
  6. data/culture/README.md +22 -0
  7. data/culture/Rakefile +5 -0
  8. data/culture/SYNC.md +70 -0
  9. data/culture/celluloid-culture.gemspec +18 -0
  10. data/culture/gems/README.md +39 -0
  11. data/culture/gems/dependencies.yml +78 -0
  12. data/culture/gems/loader.rb +101 -0
  13. data/culture/rubocop/README.md +38 -0
  14. data/culture/rubocop/lint.yml +8 -0
  15. data/culture/rubocop/metrics.yml +15 -0
  16. data/culture/rubocop/rubocop.yml +4 -0
  17. data/culture/rubocop/style.yml +48 -0
  18. data/culture/spec/gems_spec.rb +2 -0
  19. data/culture/spec/spec_helper.rb +0 -0
  20. data/culture/spec/sync_spec.rb +2 -0
  21. data/culture/sync.rb +56 -0
  22. data/culture/tasks/rspec.rake +5 -0
  23. data/culture/tasks/rubocop.rake +2 -0
  24. data/examples/basic_usage.rb +49 -0
  25. data/examples/futures.rb +38 -0
  26. data/examples/ring.rb +61 -0
  27. data/examples/simple_pmap.rb +14 -0
  28. data/examples/timers.rb +72 -0
  29. data/lib/celluloid.rb +142 -127
  30. data/lib/celluloid/actor.rb +47 -41
  31. data/lib/celluloid/actor_system.rb +75 -22
  32. data/lib/celluloid/autostart.rb +1 -1
  33. data/lib/celluloid/backported.rb +2 -0
  34. data/lib/celluloid/call/async.rb +16 -0
  35. data/lib/celluloid/call/block.rb +22 -0
  36. data/lib/celluloid/call/sync.rb +70 -0
  37. data/lib/celluloid/calls.rb +25 -114
  38. data/lib/celluloid/cell.rb +32 -20
  39. data/lib/celluloid/condition.rb +3 -3
  40. data/lib/celluloid/core_ext.rb +1 -1
  41. data/lib/celluloid/current.rb +2 -0
  42. data/lib/celluloid/deprecate.rb +18 -0
  43. data/lib/celluloid/exceptions.rb +1 -1
  44. data/lib/celluloid/fiber.rb +3 -3
  45. data/lib/celluloid/future.rb +7 -6
  46. data/lib/celluloid/group.rb +65 -0
  47. data/lib/celluloid/group/manager.rb +27 -0
  48. data/lib/celluloid/group/pool.rb +125 -0
  49. data/lib/celluloid/group/spawner.rb +71 -0
  50. data/lib/celluloid/logging.rb +5 -5
  51. data/lib/celluloid/mailbox.rb +14 -13
  52. data/lib/celluloid/mailbox/evented.rb +76 -0
  53. data/lib/celluloid/notices.rb +15 -0
  54. data/lib/celluloid/proxies.rb +12 -0
  55. data/lib/celluloid/proxy/abstract.rb +24 -0
  56. data/lib/celluloid/proxy/actor.rb +46 -0
  57. data/lib/celluloid/proxy/async.rb +36 -0
  58. data/lib/celluloid/proxy/block.rb +31 -0
  59. data/lib/celluloid/proxy/cell.rb +76 -0
  60. data/lib/celluloid/proxy/future.rb +40 -0
  61. data/lib/celluloid/proxy/sync.rb +44 -0
  62. data/lib/celluloid/rspec.rb +9 -10
  63. data/lib/celluloid/system_events.rb +16 -15
  64. data/lib/celluloid/{tasks.rb → task.rb} +21 -21
  65. data/lib/celluloid/task/fibered.rb +45 -0
  66. data/lib/celluloid/task/threaded.rb +59 -0
  67. data/lib/celluloid/test.rb +1 -1
  68. data/lib/celluloid/thread.rb +6 -1
  69. data/lib/celluloid/version.rb +3 -0
  70. data/spec/celluloid/actor_spec.rb +2 -2
  71. data/spec/celluloid/actor_system_spec.rb +35 -21
  72. data/spec/celluloid/block_spec.rb +3 -5
  73. data/spec/celluloid/calls_spec.rb +33 -11
  74. data/spec/celluloid/condition_spec.rb +16 -13
  75. data/spec/celluloid/evented_mailbox_spec.rb +1 -31
  76. data/spec/celluloid/future_spec.rb +13 -10
  77. data/spec/celluloid/group/elastic_spec.rb +0 -0
  78. data/spec/celluloid/group/manager_spec.rb +0 -0
  79. data/spec/celluloid/group/pool_spec.rb +8 -0
  80. data/spec/celluloid/group/spawner_spec.rb +8 -0
  81. data/spec/celluloid/mailbox/evented_spec.rb +27 -0
  82. data/spec/celluloid/mailbox_spec.rb +1 -3
  83. data/spec/celluloid/misc/leak_spec.rb +73 -0
  84. data/spec/celluloid/task/fibered_spec.rb +5 -0
  85. data/spec/celluloid/task/threaded_spec.rb +5 -0
  86. data/spec/celluloid/timer_spec.rb +14 -16
  87. data/spec/deprecate/actor_system_spec.rb +72 -0
  88. data/spec/deprecate/block_spec.rb +52 -0
  89. data/spec/deprecate/calls_spec.rb +57 -0
  90. data/spec/deprecate/evented_mailbox_spec.rb +34 -0
  91. data/spec/deprecate/future_spec.rb +32 -0
  92. data/spec/deprecate/internal_pool_spec.rb +4 -0
  93. data/spec/shared/actor_examples.rb +1237 -0
  94. data/spec/shared/group_examples.rb +121 -0
  95. data/{lib/celluloid/rspec → spec/shared}/mailbox_examples.rb +20 -17
  96. data/{lib/celluloid/rspec → spec/shared}/task_examples.rb +9 -8
  97. data/spec/spec_helper.rb +72 -16
  98. data/spec/support/coverage.rb +4 -0
  99. data/spec/support/crash_checking.rb +68 -0
  100. data/spec/support/debugging.rb +31 -0
  101. data/spec/support/env.rb +16 -0
  102. data/{lib/celluloid/rspec/example_actor_class.rb → spec/support/examples/actor_class.rb} +21 -2
  103. data/spec/support/examples/evented_mailbox_class.rb +27 -0
  104. data/spec/support/includer.rb +9 -0
  105. data/spec/support/logging.rb +63 -0
  106. data/spec/support/loose_threads.rb +65 -0
  107. data/spec/support/reset_class_variables.rb +27 -0
  108. data/spec/support/sleep_and_wait.rb +14 -0
  109. data/spec/support/split_logs.rb +1 -0
  110. data/spec/support/stubbing.rb +14 -0
  111. metadata +255 -95
  112. data/lib/celluloid/call_chain.rb +0 -13
  113. data/lib/celluloid/cpu_counter.rb +0 -34
  114. data/lib/celluloid/evented_mailbox.rb +0 -73
  115. data/lib/celluloid/fsm.rb +0 -186
  116. data/lib/celluloid/handlers.rb +0 -41
  117. data/lib/celluloid/internal_pool.rb +0 -159
  118. data/lib/celluloid/legacy.rb +0 -9
  119. data/lib/celluloid/links.rb +0 -36
  120. data/lib/celluloid/logger.rb +0 -93
  121. data/lib/celluloid/logging/incident.rb +0 -21
  122. data/lib/celluloid/logging/incident_logger.rb +0 -129
  123. data/lib/celluloid/logging/incident_reporter.rb +0 -48
  124. data/lib/celluloid/logging/log_event.rb +0 -20
  125. data/lib/celluloid/logging/ring_buffer.rb +0 -65
  126. data/lib/celluloid/method.rb +0 -32
  127. data/lib/celluloid/notifications.rb +0 -83
  128. data/lib/celluloid/pool_manager.rb +0 -146
  129. data/lib/celluloid/probe.rb +0 -73
  130. data/lib/celluloid/properties.rb +0 -24
  131. data/lib/celluloid/proxies/abstract_proxy.rb +0 -20
  132. data/lib/celluloid/proxies/actor_proxy.rb +0 -38
  133. data/lib/celluloid/proxies/async_proxy.rb +0 -31
  134. data/lib/celluloid/proxies/block_proxy.rb +0 -29
  135. data/lib/celluloid/proxies/cell_proxy.rb +0 -68
  136. data/lib/celluloid/proxies/future_proxy.rb +0 -35
  137. data/lib/celluloid/proxies/sync_proxy.rb +0 -36
  138. data/lib/celluloid/receivers.rb +0 -63
  139. data/lib/celluloid/registry.rb +0 -57
  140. data/lib/celluloid/responses.rb +0 -44
  141. data/lib/celluloid/rspec/actor_examples.rb +0 -1054
  142. data/lib/celluloid/signals.rb +0 -23
  143. data/lib/celluloid/stack_dump.rb +0 -133
  144. data/lib/celluloid/supervision_group.rb +0 -169
  145. data/lib/celluloid/supervisor.rb +0 -22
  146. data/lib/celluloid/task_set.rb +0 -49
  147. data/lib/celluloid/tasks/task_fiber.rb +0 -43
  148. data/lib/celluloid/tasks/task_thread.rb +0 -53
  149. data/lib/celluloid/thread_handle.rb +0 -50
  150. data/lib/celluloid/uuid.rb +0 -38
  151. data/spec/celluloid/cpu_counter_spec.rb +0 -82
  152. data/spec/celluloid/fsm_spec.rb +0 -107
  153. data/spec/celluloid/internal_pool_spec.rb +0 -52
  154. data/spec/celluloid/links_spec.rb +0 -45
  155. data/spec/celluloid/logging/ring_buffer_spec.rb +0 -38
  156. data/spec/celluloid/notifications_spec.rb +0 -120
  157. data/spec/celluloid/pool_spec.rb +0 -92
  158. data/spec/celluloid/probe_spec.rb +0 -121
  159. data/spec/celluloid/properties_spec.rb +0 -42
  160. data/spec/celluloid/registry_spec.rb +0 -64
  161. data/spec/celluloid/stack_dump_spec.rb +0 -64
  162. data/spec/celluloid/supervision_group_spec.rb +0 -65
  163. data/spec/celluloid/supervisor_spec.rb +0 -103
  164. data/spec/celluloid/tasks/task_fiber_spec.rb +0 -5
  165. data/spec/celluloid/tasks/task_thread_spec.rb +0 -5
  166. data/spec/celluloid/thread_handle_spec.rb +0 -26
  167. data/spec/celluloid/uuid_spec.rb +0 -11
@@ -1,13 +0,0 @@
1
- module Celluloid
2
- class CallChain
3
- def self.current_id=(value)
4
- Thread.current[:celluloid_chain_id] = value
5
- task = Thread.current[:celluloid_task]
6
- task.chain_id = value if task
7
- end
8
-
9
- def self.current_id
10
- Thread.current[:celluloid_chain_id]
11
- end
12
- end
13
- end
@@ -1,34 +0,0 @@
1
- module Celluloid
2
- module CPUCounter
3
- class << self
4
- def cores
5
- @cores ||= count_cores
6
- end
7
-
8
- private
9
-
10
- def count_cores
11
- result = from_env || from_sysdev || from_sysctl
12
- Integer(result.to_s[/\d+/], 10) if result
13
- end
14
-
15
- def from_env
16
- result = ENV['NUMBER_OF_PROCESSORS']
17
- result if result
18
- end
19
-
20
- def from_sysdev
21
- ::IO.read('/sys/devices/system/cpu/present').split('-').last.to_i + 1
22
- rescue Errno::ENOENT
23
- result = Dir['/sys/devices/system/cpu/cpu*'].count { |n| n =~ /cpu\d+/ }
24
- result unless result.zero?
25
- end
26
-
27
- def from_sysctl
28
- result = `sysctl -n hw.ncpu`
29
- result if $?.success?
30
- rescue Errno::ENOENT
31
- end
32
- end
33
- end
34
- end
@@ -1,73 +0,0 @@
1
- module Celluloid
2
- # An alternative implementation of Celluloid::Mailbox using Reactor
3
- class EventedMailbox < Celluloid::Mailbox
4
- attr_reader :reactor
5
-
6
- def initialize(reactor_class)
7
- super()
8
- # @condition won't be used in the class.
9
- @reactor = reactor_class.new
10
- end
11
-
12
- # Add a message to the Mailbox
13
- def <<(message)
14
- @mutex.lock
15
- begin
16
- if mailbox_full || @dead
17
- dead_letter(message)
18
- return
19
- end
20
- if message.is_a?(SystemEvent)
21
- # SystemEvents are high priority messages so they get added to the
22
- # head of our message queue instead of the end
23
- @messages.unshift message
24
- else
25
- @messages << message
26
- end
27
-
28
- current_actor = Thread.current[:celluloid_actor]
29
- @reactor.wakeup unless current_actor && current_actor.mailbox == self
30
- rescue IOError
31
- Logger.crash "reactor crashed", $!
32
- dead_letter(message)
33
- ensure
34
- @mutex.unlock rescue nil
35
- end
36
- nil
37
- end
38
-
39
- # Receive a message from the Mailbox
40
- def check(timeout = nil, &block)
41
- # Get a message if it is available and process it immediately if possible:
42
- if message = next_message(block)
43
- return message
44
- end
45
-
46
- # ... otherwise, run the reactor once, either blocking or will return
47
- # after the given timeout:
48
- @reactor.run_once(timeout)
49
-
50
- # No message was received:
51
- return nil
52
- rescue IOError
53
- raise MailboxShutdown, "mailbox shutdown called during receive"
54
- end
55
-
56
- # Obtain the next message from the mailbox that matches the given block
57
- def next_message(block)
58
- @mutex.lock
59
- begin
60
- super(&block)
61
- ensure
62
- @mutex.unlock rescue nil
63
- end
64
- end
65
-
66
- # Cleanup any IO objects this Mailbox may be using
67
- def shutdown
68
- super do
69
- @reactor.shutdown
70
- end
71
- end
72
- end
73
- end
@@ -1,186 +0,0 @@
1
- module Celluloid
2
- # Simple finite state machines with integrated Celluloid timeout support
3
- # Inspired by Erlang's gen_fsm (http://www.erlang.org/doc/man/gen_fsm.html)
4
- #
5
- # Basic usage:
6
- #
7
- # class MyMachine
8
- # include Celluloid::FSM # NOTE: this does NOT pull in the Celluloid module
9
- # end
10
- #
11
- # Inside an actor:
12
- #
13
- # #
14
- # machine = MyMachine.new(current_actor)
15
- module FSM
16
- class UnattachedError < Celluloid::Error; end # Not attached to an actor
17
-
18
- DEFAULT_STATE = :default # Default state name unless one is explicitly set
19
-
20
- # Included hook to extend class methods
21
- def self.included(klass)
22
- klass.send :extend, ClassMethods
23
- end
24
-
25
- module ClassMethods
26
- # Obtain or set the default state
27
- # Passing a state name sets the default state
28
- def default_state(new_default = nil)
29
- if new_default
30
- @default_state = new_default.to_sym
31
- else
32
- defined?(@default_state) ? @default_state : DEFAULT_STATE
33
- end
34
- end
35
-
36
- # Obtain the valid states for this FSM
37
- def states
38
- @states ||= {}
39
- end
40
-
41
- # Declare an FSM state and optionally provide a callback block to fire
42
- # Options:
43
- # * to: a state or array of states this state can transition to
44
- def state(*args, &block)
45
- if args.last.is_a? Hash
46
- # Stringify keys :/
47
- options = args.pop.inject({}) { |h,(k,v)| h[k.to_s] = v; h }
48
- else
49
- options = {}
50
- end
51
-
52
- args.each do |name|
53
- name = name.to_sym
54
- default_state name if options['default']
55
- states[name] = State.new(name, options['to'], &block)
56
- end
57
- end
58
- end
59
-
60
- attr_reader :actor
61
-
62
- # Be kind and call super if you must redefine initialize
63
- def initialize(actor = nil)
64
- @state = self.class.default_state
65
- @delayed_transition = nil
66
- @actor = actor
67
- @actor ||= Celluloid.current_actor if Celluloid.actor?
68
- end
69
-
70
- # Obtain the current state of the FSM
71
- attr_reader :state
72
-
73
- # Attach this FSM to an actor. This allows FSMs to wait for and initiate
74
- # events in the context of a particular actor
75
- def attach(actor)
76
- @actor = actor
77
- end
78
- alias_method :actor=, :attach
79
-
80
- # Transition to another state
81
- # Options:
82
- # * delay: don't transition immediately, wait the given number of seconds.
83
- # This will return a Celluloid::Timer object you can use to
84
- # cancel the pending state transition.
85
- #
86
- # Note: making additional state transitions will cancel delayed transitions
87
- def transition(state_name, options = {})
88
- new_state = validate_and_sanitize_new_state(state_name)
89
- return unless new_state
90
-
91
- if handle_delayed_transitions(new_state, options[:delay])
92
- return @delayed_transition
93
- end
94
-
95
- transition_with_callbacks!(new_state)
96
- end
97
-
98
- # Immediate state transition with no sanity checks, or callbacks. "Dangerous!"
99
- def transition!(state_name)
100
- @state = state_name
101
- end
102
-
103
- protected
104
-
105
- def validate_and_sanitize_new_state(state_name)
106
- state_name = state_name.to_sym
107
-
108
- return if current_state_name == state_name
109
-
110
- if current_state and not current_state.valid_transition? state_name
111
- valid = current_state.transitions.map(&:to_s).join(", ")
112
- raise ArgumentError, "#{self.class} can't change state from '#{@state}' to '#{state_name}', only to: #{valid}"
113
- end
114
-
115
- new_state = states[state_name]
116
-
117
- unless new_state
118
- return if state_name == default_state
119
- raise ArgumentError, "invalid state for #{self.class}: #{state_name}"
120
- end
121
-
122
- new_state
123
- end
124
-
125
- def transition_with_callbacks!(state_name)
126
- transition! state_name.name
127
- state_name.call(self)
128
- end
129
-
130
- def states
131
- self.class.states
132
- end
133
-
134
- def default_state
135
- self.class.default_state
136
- end
137
-
138
- def current_state
139
- states[@state]
140
- end
141
-
142
- def current_state_name
143
- current_state && current_state.name || ''
144
- end
145
-
146
- def handle_delayed_transitions(new_state, delay)
147
- if delay
148
- raise UnattachedError, "can't delay unless attached" unless @actor
149
- @delayed_transition.cancel if @delayed_transition
150
-
151
- @delayed_transition = @actor.after(delay) do
152
- transition_with_callbacks!(new_state)
153
- end
154
-
155
- return @delayed_transition
156
- end
157
-
158
- if defined?(@delayed_transition) and @delayed_transition
159
- @delayed_transition.cancel
160
- @delayed_transition = nil
161
- end
162
- end
163
-
164
- # FSM states as declared by Celluloid::FSM.state
165
- class State
166
- attr_reader :name, :transitions
167
-
168
- def initialize(name, transitions = nil, &block)
169
- @name, @block = name, block
170
- @transitions = nil
171
- @transitions = Array(transitions).map { |t| t.to_sym } if transitions
172
- end
173
-
174
- def call(obj)
175
- obj.instance_eval(&@block) if @block
176
- end
177
-
178
- def valid_transition?(new_state)
179
- # All transitions are allowed unless expressly
180
- return true unless @transitions
181
-
182
- @transitions.include? new_state.to_sym
183
- end
184
- end
185
- end
186
- end
@@ -1,41 +0,0 @@
1
- require 'set'
2
-
3
- module Celluloid
4
- class Handlers
5
- def initialize
6
- @handlers = Set.new
7
- end
8
-
9
- def handle(*patterns, &block)
10
- patterns.each do |pattern|
11
- handler = Handler.new pattern, block
12
- @handlers << handler
13
- end
14
- end
15
-
16
- # Handle incoming messages
17
- def handle_message(message)
18
- if handler = @handlers.find { |h| h.match(message) }
19
- handler.call message
20
- handler
21
- end
22
- end
23
- end
24
-
25
- # Methods blocking on a call to receive
26
- class Handler
27
- def initialize(pattern, block)
28
- @pattern = pattern
29
- @block = block
30
- end
31
-
32
- # Match a message with this receiver's block
33
- def match(message)
34
- @pattern === message
35
- end
36
-
37
- def call(message)
38
- @block.call message
39
- end
40
- end
41
- end
@@ -1,159 +0,0 @@
1
- require 'thread'
2
-
3
- module Celluloid
4
- # Maintain a thread pool FOR SPEED!!
5
- class InternalPool
6
- attr_accessor :max_idle
7
-
8
- def initialize
9
- @mutex = Mutex.new
10
- @idle_threads = []
11
- @all_threads = []
12
- @busy_size = 0
13
- @idle_size = 0
14
-
15
- # TODO: should really adjust this based on usage
16
- @max_idle = 16
17
- @running = true
18
- end
19
-
20
- def busy_size
21
- @busy_size
22
- end
23
-
24
- def idle_size
25
- @idle_size
26
- end
27
-
28
- def assert_running
29
- raise Error, "Thread pool is not running" unless running?
30
- end
31
-
32
- def assert_inactive
33
- if active?
34
- message = "Thread pool is still active"
35
- if defined?(JRUBY_VERSION)
36
- Celluloid.logger.warn message
37
- else
38
- raise Error, message
39
- end
40
- end
41
- end
42
-
43
- def running?
44
- @running
45
- end
46
-
47
- def active?
48
- busy_size + idle_size > 0
49
- end
50
-
51
- def each
52
- to_a.each {|thread| yield thread }
53
- end
54
-
55
- def to_a
56
- @mutex.synchronize { @all_threads.dup }
57
- end
58
-
59
- # Get a thread from the pool, running the given block
60
- def get(&block)
61
- @mutex.synchronize do
62
- assert_running
63
-
64
- begin
65
- if @idle_threads.empty?
66
- thread = create
67
- else
68
- thread = @idle_threads.pop
69
- @idle_size = @idle_threads.length
70
- end
71
- end until thread.status # handle crashed threads
72
-
73
- thread.busy = true
74
- @busy_size += 1
75
- thread[:celluloid_queue] << block
76
- thread
77
- end
78
- end
79
-
80
- # Return a thread to the pool
81
- def put(thread)
82
- @mutex.synchronize do
83
- thread.busy = false
84
- if idle_size + 1 >= @max_idle
85
- thread[:celluloid_queue] << nil
86
- @busy_size -= 1
87
- @all_threads.delete(thread)
88
- else
89
- @idle_threads.push thread
90
- @busy_size -= 1
91
- @idle_size = @idle_threads.length
92
- clean_thread_locals(thread)
93
- end
94
- end
95
- end
96
-
97
- def shutdown
98
- @mutex.synchronize do
99
- finalize
100
- @all_threads.each do |thread|
101
- thread[:celluloid_queue] << nil
102
- end
103
- @all_threads.clear
104
- @idle_threads.clear
105
- @busy_size = 0
106
- @idle_size = 0
107
- end
108
- end
109
-
110
- def kill
111
- @mutex.synchronize do
112
- finalize
113
- @running = false
114
-
115
- @all_threads.shift.kill until @all_threads.empty?
116
- @idle_threads.clear
117
- @busy_size = 0
118
- @idle_size = 0
119
- end
120
- end
121
-
122
- private
123
-
124
- # Create a new thread with an associated queue of procs to run
125
- def create
126
- queue = Queue.new
127
- thread = Thread.new do
128
- while proc = queue.pop
129
- begin
130
- proc.call
131
- rescue => ex
132
- Logger.crash("thread crashed", ex)
133
- end
134
-
135
- put thread
136
- end
137
- end
138
-
139
- thread[:celluloid_queue] = queue
140
- # @idle_threads << thread
141
- @all_threads << thread
142
- thread
143
- end
144
-
145
- # Clean the thread locals of an incoming thread
146
- def clean_thread_locals(thread)
147
- thread.keys.each do |key|
148
- next if key == :celluloid_queue
149
-
150
- # Ruby seems to lack an API for deleting thread locals. WTF, Ruby?
151
- thread[key] = nil
152
- end
153
- end
154
-
155
- def finalize
156
- @max_idle = 0
157
- end
158
- end
159
- end