celluloid-pool 0.10.0.pre4 → 0.11.0.pre0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile +1 -23
- data/celluloid-pool.gemspec +2 -2
- data/lib/celluloid/supervision/container/behavior/pool.rb +23 -13
- data/lib/celluloid/supervision/container/pool.rb +72 -40
- metadata +88 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8a5b5a00045d8f76b4aacfed6fd8329459431d1
|
|
4
|
+
data.tar.gz: 3ee6985ed4b292e291f77433ea6ec64d548e902e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e685ea4613ddf4a7b3f4aaa56489afec5fc7930188ca539347c60984fe810d7bf7a51aa61491ccce4a51f81b5f45c3b30ff38512e5c7de0502fc65864785131f
|
|
7
|
+
data.tar.gz: 28b9ba837503fcd60f28f4bfeb16f6c7019c0ad44c896b290a25a5055c5936d2865500d9c018c0358c2bde4da5263e3f3340c3b20f26ab22acdfd28e5923f943
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -1,24 +1,2 @@
|
|
|
1
1
|
require File.expand_path("../culture/sync", __FILE__)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
gemspec #de development_group: :gem_build_tools
|
|
5
|
-
|
|
6
|
-
group :development do
|
|
7
|
-
gem "pry"
|
|
8
|
-
# de gem 'guard'
|
|
9
|
-
# de gem 'guard-rspec'
|
|
10
|
-
# de gem 'rb-fsevent', '~> 0.9.1' if RUBY_PLATFORM =~ /darwin/
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
group :test do
|
|
14
|
-
gem "dotenv", "~> 2.0"
|
|
15
|
-
gem "nenv"
|
|
16
|
-
gem "benchmark_suite"
|
|
17
|
-
gem "rspec", "~> 3.2"
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
group :gem_build_tools do
|
|
21
|
-
gem "rake"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
Celluloid::Sync.gems(self)
|
|
2
|
+
Celluloid::Sync::Gemfile[self]
|
data/celluloid-pool.gemspec
CHANGED
|
@@ -3,7 +3,7 @@ require File.expand_path("../culture/sync", __FILE__)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |gem|
|
|
5
5
|
gem.name = "celluloid-pool"
|
|
6
|
-
gem.version = "0.
|
|
6
|
+
gem.version = "0.11.0.pre0"
|
|
7
7
|
gem.authors = ["Tony Arcieri", "Tim Carey-Smith", "digitalextremist //"]
|
|
8
8
|
gem.email = ["tony.arcieri@gmail.com", "code@extremist.digital"]
|
|
9
9
|
|
|
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
|
|
|
15
15
|
gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|examples|spec|features)/}) }
|
|
16
16
|
gem.require_paths = ["lib"]
|
|
17
17
|
|
|
18
|
-
Celluloid::Sync
|
|
18
|
+
Celluloid::Sync::Gemspec[gem]
|
|
19
19
|
end
|
|
@@ -2,29 +2,32 @@ require "set"
|
|
|
2
2
|
|
|
3
3
|
module Celluloid
|
|
4
4
|
module ClassMethods
|
|
5
|
+
extend Forwardable
|
|
6
|
+
def_delegators :"Celluloid::Supervision::Container::Pool", :pooling_options
|
|
5
7
|
# Create a new pool of workers. Accepts the following options:
|
|
6
8
|
#
|
|
7
9
|
# * size: how many workers to create. Default is worker per CPU core
|
|
8
10
|
# * args: array of arguments to pass when creating a worker
|
|
9
11
|
#
|
|
10
|
-
def pool(config={})
|
|
11
|
-
Celluloid.
|
|
12
|
-
|
|
12
|
+
def pool(config={}, &block)
|
|
13
|
+
_ = Celluloid.supervise(pooling_options(config, block: block, actors: self))
|
|
14
|
+
_.actors.last
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
# Same as pool, but links to the pool manager
|
|
16
|
-
def pool_link(klass, config={})
|
|
17
|
-
Supervision::Container::Pool.new_link(
|
|
18
|
-
config.merge(args: [{workers: klass}]),
|
|
19
|
-
)
|
|
18
|
+
def pool_link(klass, config={}, &block)
|
|
19
|
+
Supervision::Container::Pool.new_link(pooling_options(config, block: block, actors: klass))
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
module Supervision
|
|
24
24
|
class Container
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
extend Forwardable
|
|
26
|
+
def_delegators :"Celluloid::Supervision::Container::Pool", :pooling_options
|
|
27
|
+
|
|
28
|
+
def pool(klass, config={}, &block)
|
|
29
|
+
_ = supervise(pooling_options(config, block: block, actors: klass))
|
|
30
|
+
_.actors.last
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
class Instance
|
|
@@ -33,9 +36,9 @@ module Celluloid
|
|
|
33
36
|
|
|
34
37
|
class << self
|
|
35
38
|
# Register a pool of actors to be launched on group startup
|
|
36
|
-
def pool(klass,
|
|
39
|
+
def pool(klass, config, &block)
|
|
37
40
|
blocks << lambda do |container|
|
|
38
|
-
container.pool(klass,
|
|
41
|
+
container.pool(klass, config, &block)
|
|
39
42
|
end
|
|
40
43
|
end
|
|
41
44
|
end
|
|
@@ -43,10 +46,17 @@ module Celluloid
|
|
|
43
46
|
class Pool
|
|
44
47
|
include Behavior
|
|
45
48
|
|
|
49
|
+
class << self
|
|
50
|
+
def pooling_options(config={},mixins={})
|
|
51
|
+
combined = { :type => Celluloid::Supervision::Container::Pool }.merge(config).merge(mixins)
|
|
52
|
+
combined[:args] = [[:block, :actors, :size, :args].inject({}) { |e,p| e[p] = combined.delete(p) if combined[p]; e }]
|
|
53
|
+
combined
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
46
57
|
identifier! :size, :pool
|
|
47
58
|
|
|
48
59
|
configuration do
|
|
49
|
-
puts "configuring pool"
|
|
50
60
|
@supervisor = Container::Pool
|
|
51
61
|
@method = "pool_link"
|
|
52
62
|
@pool = true
|
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
module Celluloid
|
|
2
2
|
module Supervision
|
|
3
3
|
class Container
|
|
4
|
-
# Manages a fixed-size pool of
|
|
5
|
-
# Delegates work (i.e. methods) and supervises
|
|
4
|
+
# Manages a fixed-size pool of actors
|
|
5
|
+
# Delegates work (i.e. methods) and supervises actors
|
|
6
6
|
# Don't use this class directly. Instead use MyKlass.pool
|
|
7
7
|
class Pool
|
|
8
|
-
|
|
9
8
|
include Celluloid
|
|
10
9
|
|
|
11
10
|
trap_exit :__crash_handler__
|
|
12
11
|
finalizer :__shutdown__
|
|
13
12
|
|
|
13
|
+
attr_reader :size, :actors
|
|
14
|
+
|
|
14
15
|
def initialize(options={})
|
|
15
16
|
@idle = []
|
|
16
17
|
@busy = []
|
|
17
|
-
@
|
|
18
|
-
@
|
|
19
|
-
@
|
|
18
|
+
@klass = options[:actors]
|
|
19
|
+
@actors = Set.new
|
|
20
|
+
@mutex = Mutex.new
|
|
20
21
|
|
|
21
|
-
#de options = Supervision::Configuration.options(options)
|
|
22
22
|
@size = options[:size] || [Celluloid.cores || 2, 2].max
|
|
23
23
|
@args = options[:args] ? Array(options[:args]) : []
|
|
24
24
|
|
|
25
|
-
fail ArgumentError, "minimum pool size is 2" if @size < 2
|
|
26
|
-
|
|
27
25
|
# Do this last since it can suspend and/or crash
|
|
28
|
-
@idle = @size.times.map {
|
|
26
|
+
@idle = @size.times.map { __spawn_actor__ }
|
|
29
27
|
end
|
|
30
28
|
|
|
31
29
|
def __shutdown__
|
|
32
30
|
# TODO: these can be nil if initializer crashes
|
|
33
|
-
terminators =
|
|
31
|
+
terminators = @actors.map do |actor|
|
|
34
32
|
begin
|
|
35
33
|
actor.future(:terminate)
|
|
36
34
|
rescue DeadActorError
|
|
@@ -41,24 +39,23 @@ module Celluloid
|
|
|
41
39
|
end
|
|
42
40
|
|
|
43
41
|
def _send_(method, *args, &block)
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
actor = __provision_actor__
|
|
46
43
|
begin
|
|
47
|
-
|
|
44
|
+
actor._send_ method, *args, &block
|
|
48
45
|
rescue DeadActorError # if we get a dead actor out of the pool
|
|
49
46
|
wait :respawn_complete
|
|
50
|
-
|
|
47
|
+
actor = __provision_actor__
|
|
51
48
|
retry
|
|
52
49
|
rescue Exception => ex
|
|
53
50
|
abort ex
|
|
54
51
|
ensure
|
|
55
|
-
if
|
|
56
|
-
@idle <<
|
|
57
|
-
@busy.delete
|
|
52
|
+
if actor.alive?
|
|
53
|
+
@idle << actor
|
|
54
|
+
@busy.delete actor
|
|
58
55
|
|
|
59
|
-
# Broadcast that
|
|
56
|
+
# Broadcast that actor is done processing and
|
|
60
57
|
# waiting idle
|
|
61
|
-
signal :
|
|
58
|
+
signal :actor_idle
|
|
62
59
|
end
|
|
63
60
|
end
|
|
64
61
|
end
|
|
@@ -87,20 +84,18 @@ module Celluloid
|
|
|
87
84
|
_send_ :inspect
|
|
88
85
|
end
|
|
89
86
|
|
|
90
|
-
attr_reader :size
|
|
91
|
-
|
|
92
87
|
def size=(new_size)
|
|
93
88
|
new_size = [0, new_size].max
|
|
94
|
-
|
|
95
89
|
if new_size > size
|
|
96
90
|
delta = new_size - size
|
|
97
|
-
delta.times { @idle <<
|
|
91
|
+
delta.times { @idle << __spawn_actor__ }
|
|
98
92
|
else
|
|
99
93
|
(size - new_size).times do
|
|
100
|
-
|
|
101
|
-
unlink
|
|
102
|
-
@busy.delete
|
|
103
|
-
|
|
94
|
+
actor = __provision_actor__
|
|
95
|
+
unlink actor
|
|
96
|
+
@busy.delete actor
|
|
97
|
+
@actors.delete actor
|
|
98
|
+
actor.terminate
|
|
104
99
|
end
|
|
105
100
|
end
|
|
106
101
|
@size = new_size
|
|
@@ -114,28 +109,65 @@ module Celluloid
|
|
|
114
109
|
@idle.length
|
|
115
110
|
end
|
|
116
111
|
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
def __idle?(actor)
|
|
113
|
+
@idle.include? actor
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def __busy?(actor)
|
|
117
|
+
@busy.include? actor
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def __busy
|
|
121
|
+
@busy
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def __idle
|
|
125
|
+
@idle
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def __idling?
|
|
129
|
+
@mutex.synchronize { @idle.empty? }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def __state(actor)
|
|
133
|
+
return :busy if __busy?(actor)
|
|
134
|
+
return :idle if __idle?(actor)
|
|
135
|
+
:missing
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Instantiate an actor, add it to the actor Set, and return it
|
|
139
|
+
def __spawn_actor__
|
|
140
|
+
actor = @klass.new_link(*@args)
|
|
141
|
+
@mutex.synchronize { @actors.add(actor) }
|
|
142
|
+
actor
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Provision a new actor ( take it out of idle, move it into busy, and avail it )
|
|
146
|
+
def __provision_actor__
|
|
119
147
|
Task.current.guard_warnings = true
|
|
120
|
-
while
|
|
121
|
-
# Wait for responses from one of the busy
|
|
148
|
+
while __idling?
|
|
149
|
+
# Wait for responses from one of the busy actors
|
|
122
150
|
response = exclusive { receive { |msg| msg.is_a?(Internals::Response) } }
|
|
123
151
|
Thread.current[:celluloid_actor].handle_message(response)
|
|
124
152
|
end
|
|
125
153
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
154
|
+
@mutex.synchronize {
|
|
155
|
+
actor = @idle.shift
|
|
156
|
+
@busy << actor
|
|
157
|
+
actor
|
|
158
|
+
}
|
|
130
159
|
end
|
|
131
160
|
|
|
132
161
|
# Spawn a new worker for every crashed one
|
|
133
162
|
def __crash_handler__(actor, reason)
|
|
134
|
-
@
|
|
135
|
-
|
|
163
|
+
@mutex.synchronize {
|
|
164
|
+
@busy.delete actor
|
|
165
|
+
@idle.delete actor
|
|
166
|
+
@actors.delete actor
|
|
167
|
+
}
|
|
136
168
|
return unless reason
|
|
137
169
|
|
|
138
|
-
@idle <<
|
|
170
|
+
@idle << __spawn_actor__
|
|
139
171
|
signal :respawn_complete
|
|
140
172
|
end
|
|
141
173
|
|
|
@@ -175,7 +207,7 @@ module Celluloid
|
|
|
175
207
|
def method(meth)
|
|
176
208
|
super
|
|
177
209
|
rescue NameError
|
|
178
|
-
@
|
|
210
|
+
@klass.instance_method(meth.to_sym)
|
|
179
211
|
end
|
|
180
212
|
end
|
|
181
213
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: celluloid-pool
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0.pre0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tony Arcieri
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2015-05-
|
|
13
|
+
date: 2015-05-09 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -32,7 +32,7 @@ dependencies:
|
|
|
32
32
|
- - '>='
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
34
|
version: '0'
|
|
35
|
-
name:
|
|
35
|
+
name: nenv
|
|
36
36
|
prerelease: false
|
|
37
37
|
type: :runtime
|
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -46,7 +46,7 @@ dependencies:
|
|
|
46
46
|
- - '>='
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
48
|
version: '0'
|
|
49
|
-
name:
|
|
49
|
+
name: dotenv
|
|
50
50
|
prerelease: false
|
|
51
51
|
type: :runtime
|
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -54,6 +54,90 @@ dependencies:
|
|
|
54
54
|
- - '>='
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
56
|
version: '0'
|
|
57
|
+
- !ruby/object:Gem::Dependency
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - '>='
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
name: benchmark_suite
|
|
64
|
+
prerelease: false
|
|
65
|
+
type: :development
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - '>='
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
71
|
+
- !ruby/object:Gem::Dependency
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - '>='
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
name: rubocop
|
|
78
|
+
prerelease: false
|
|
79
|
+
type: :development
|
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - '>='
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
- !ruby/object:Gem::Dependency
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - '>='
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
name: pry
|
|
92
|
+
prerelease: false
|
|
93
|
+
type: :development
|
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - '>='
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
name: rake
|
|
106
|
+
prerelease: false
|
|
107
|
+
type: :development
|
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - '>='
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '0'
|
|
113
|
+
- !ruby/object:Gem::Dependency
|
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
|
115
|
+
requirements:
|
|
116
|
+
- - '>='
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
version: '0'
|
|
119
|
+
name: rspec
|
|
120
|
+
prerelease: false
|
|
121
|
+
type: :development
|
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - '>='
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '0'
|
|
127
|
+
- !ruby/object:Gem::Dependency
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
requirements:
|
|
130
|
+
- - '>='
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: '0'
|
|
133
|
+
name: coveralls
|
|
134
|
+
prerelease: false
|
|
135
|
+
type: :development
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
requirements:
|
|
138
|
+
- - '>='
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '0'
|
|
57
141
|
- !ruby/object:Gem::Dependency
|
|
58
142
|
requirement: !ruby/object:Gem::Requirement
|
|
59
143
|
requirements:
|