celluloid-pool 0.10.0.pre4 → 0.11.0.pre0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|