autorespawn 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/autorespawn.gemspec +1 -0
- data/lib/autorespawn.rb +1 -0
- data/lib/autorespawn/manager.rb +34 -2
- data/lib/autorespawn/program_id.rb +9 -2
- data/lib/autorespawn/self.rb +1 -1
- data/lib/autorespawn/slave.rb +23 -4
- data/lib/autorespawn/tracked_file.rb +25 -0
- data/lib/autorespawn/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7611aabbaa1ad2c8d52ca80fa16ea0c66960dec5
|
4
|
+
data.tar.gz: 72812f7b5baf6deefa772122cd8cee4f29f4ff53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d94adfafc6192c05751edfb426a4f0fda3077bdc111ccdfdda44374feb4bba8410308bc13a3053e1d4017b3a20462b14b82a69acf9dbe3a67ecacfed67e93962
|
7
|
+
data.tar.gz: f466b32d71fdf8a7b14216c85025c20727f14a361331d779c98f6e3a5deb317b8a33e2c9d3ced02c14075add52fd78e58b30d53147dedf71ea96fffa8ea86152
|
data/.gitignore
CHANGED
data/autorespawn.gemspec
CHANGED
@@ -31,5 +31,6 @@ EOD
|
|
31
31
|
spec.add_development_dependency "minitest", ">= 5.0", "~> 5.0"
|
32
32
|
spec.add_development_dependency "fakefs", ">= 0.6", "~> 0.6.0"
|
33
33
|
spec.add_development_dependency 'flexmock', ">= 2.0", '~> 2.0'
|
34
|
+
spec.add_development_dependency "simplecov", '>= 0.11'
|
34
35
|
spec.add_development_dependency "coveralls"
|
35
36
|
end
|
data/lib/autorespawn.rb
CHANGED
data/lib/autorespawn/manager.rb
CHANGED
@@ -25,6 +25,9 @@ class Manager
|
|
25
25
|
attr_reader :active_slaves
|
26
26
|
# @return [Array<Slave>] list of slaves explicitely queued with {#queue}
|
27
27
|
attr_reader :queued_slaves
|
28
|
+
# @return [Hash<Pathname,TrackedFile>] the whole set of files that are
|
29
|
+
# tracked by this manager's slaves
|
30
|
+
attr_reader :tracked_files
|
28
31
|
|
29
32
|
# @!group Hooks
|
30
33
|
|
@@ -74,6 +77,7 @@ def initialize(name: nil, parallel_level: 1)
|
|
74
77
|
@workers = Array.new
|
75
78
|
@name = name
|
76
79
|
@seed = ProgramID.for_self
|
80
|
+
@tracked_files = Hash.new
|
77
81
|
|
78
82
|
@self_slave = Self.new(name: name)
|
79
83
|
@workers << self_slave
|
@@ -121,6 +125,7 @@ def active?(slave)
|
|
121
125
|
# reporting / tracking
|
122
126
|
def add_slave(*cmdline, name: nil, **spawn_options)
|
123
127
|
slave = Slave.new(*cmdline, name: name, seed: seed, **spawn_options)
|
128
|
+
slave.needed!
|
124
129
|
register_slave(slave)
|
125
130
|
slave
|
126
131
|
end
|
@@ -168,11 +173,20 @@ def collect_finished_slaves
|
|
168
173
|
def process_finished_slave(pid, status)
|
169
174
|
return if !(slave = active_slaves.delete(pid))
|
170
175
|
|
171
|
-
slave.finished(status)
|
176
|
+
if slave.finished(status).empty?
|
177
|
+
# Do not register the slave if it is already marked as needed?
|
178
|
+
slave.each_tracked_file(with_status: true) do |path, mtime, size|
|
179
|
+
tracker = (tracked_files[path] ||= TrackedFile.new(path, mtime: mtime, size: size))
|
180
|
+
tracker.slaves << slave
|
181
|
+
end
|
182
|
+
slave.not_needed!
|
183
|
+
end
|
184
|
+
|
172
185
|
slave.subcommands.each do |name, cmdline, spawn_options|
|
173
186
|
add_slave(*cmdline, name: name, **spawn_options)
|
174
187
|
end
|
175
188
|
seed.merge!(slave.program_id)
|
189
|
+
|
176
190
|
run_hook :on_slave_finished, slave
|
177
191
|
slave
|
178
192
|
end
|
@@ -214,10 +228,25 @@ def run
|
|
214
228
|
end
|
215
229
|
end
|
216
230
|
|
231
|
+
def trigger_slaves_as_necessary
|
232
|
+
tracked_files.delete_if do |path, tracker|
|
233
|
+
tracker.slaves.delete_if(&:needed?)
|
234
|
+
if tracker.slaves.empty?
|
235
|
+
true
|
236
|
+
elsif tracker.update
|
237
|
+
tracker.slaves.each(&:needed!)
|
238
|
+
true
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
217
243
|
# Wait for children to terminate and spawns them when needed
|
218
|
-
def poll(autospawn: true)
|
244
|
+
def poll(autospawn: true, update_files: true)
|
219
245
|
finished_slaves = collect_finished_slaves
|
220
246
|
new_slaves = Array.new
|
247
|
+
|
248
|
+
trigger_slaves_as_necessary
|
249
|
+
|
221
250
|
while active_slaves.size < parallel_level + 1
|
222
251
|
if slave = queued_slaves.find { |s| !s.running? }
|
223
252
|
queued_slaves.delete(slave)
|
@@ -228,6 +257,9 @@ def poll(autospawn: true)
|
|
228
257
|
|
229
258
|
if slave
|
230
259
|
slave.spawn
|
260
|
+
# We manually track the slave's needed flag, just forcefully
|
261
|
+
# set it to false at that point
|
262
|
+
slave.not_needed!
|
231
263
|
run_hook :__on_slave_start, slave
|
232
264
|
new_slaves << slave
|
233
265
|
active_slaves[slave.pid] = slave
|
@@ -128,8 +128,15 @@ def refresh
|
|
128
128
|
# Enumerate the path of all the files that are being tracked
|
129
129
|
#
|
130
130
|
# @yieldparam [Pathname] path
|
131
|
-
def each_tracked_file(&block)
|
132
|
-
|
131
|
+
def each_tracked_file(with_status: false, &block)
|
132
|
+
if with_status
|
133
|
+
return enum_for(__method__, with_status: true) if !block_given?
|
134
|
+
files.each do |path, info|
|
135
|
+
yield(path, info.mtime, info.size)
|
136
|
+
end
|
137
|
+
else
|
138
|
+
files.keys.each(&block)
|
139
|
+
end
|
133
140
|
end
|
134
141
|
|
135
142
|
# Returns a string that can ID this program
|
data/lib/autorespawn/self.rb
CHANGED
data/lib/autorespawn/slave.rb
CHANGED
@@ -61,6 +61,11 @@ def inspect
|
|
61
61
|
"#<Autorespawn::Slave #{object_id.to_s(16)} #{cmdline.join(" ")}>"
|
62
62
|
end
|
63
63
|
|
64
|
+
# Enumerate the files that are tracked for {#needed?}
|
65
|
+
def each_tracked_file(with_status: false, &block)
|
66
|
+
@program_id.each_tracked_file(with_status: with_status, &block)
|
67
|
+
end
|
68
|
+
|
64
69
|
def to_s; inspect end
|
65
70
|
|
66
71
|
# Register files on the program ID
|
@@ -85,7 +90,7 @@ def spawn
|
|
85
90
|
SLAVE_RESULT_ENV => result_w.fileno.to_s)
|
86
91
|
|
87
92
|
program_id.refresh
|
88
|
-
@needed =
|
93
|
+
@needed = nil
|
89
94
|
pid = Kernel.spawn(env, *cmdline, initial_r => initial_r, result_w => result_w, **spawn_options)
|
90
95
|
initial_r.close
|
91
96
|
result_w.close
|
@@ -113,7 +118,11 @@ def spawn
|
|
113
118
|
# Whether this slave would need to be spawned, either because it has
|
114
119
|
# never be, or because the program ID changed
|
115
120
|
def needed?
|
116
|
-
|
121
|
+
if running? then false
|
122
|
+
elsif !@needed.nil?
|
123
|
+
@needed
|
124
|
+
else program_id.changed?
|
125
|
+
end
|
117
126
|
end
|
118
127
|
|
119
128
|
# Marks this slave for execution
|
@@ -127,11 +136,18 @@ def needed!
|
|
127
136
|
@needed = true
|
128
137
|
end
|
129
138
|
|
130
|
-
#
|
139
|
+
# Forces {#needed?} to return false
|
140
|
+
#
|
141
|
+
# Call {#needed_auto} to revert back to determining if the slave is
|
142
|
+
# needed or not using the tracked files
|
131
143
|
def not_needed!
|
132
144
|
@needed = false
|
133
145
|
end
|
134
146
|
|
147
|
+
def needed_auto
|
148
|
+
@needed = nil
|
149
|
+
end
|
150
|
+
|
135
151
|
# Whether the slave is running
|
136
152
|
def running?
|
137
153
|
pid && !status
|
@@ -177,6 +193,9 @@ def success?
|
|
177
193
|
# Announce that the slave already finished, with the given exit status
|
178
194
|
#
|
179
195
|
# @param [Process::Status] the exit status
|
196
|
+
# @return [Array<Pathname>] a set of files that either changed or got
|
197
|
+
# added since the call to {#spawn}. If not empty, the slave calls
|
198
|
+
# {#needed!} by itself to force a re-execution
|
180
199
|
def finished(status)
|
181
200
|
@status = status
|
182
201
|
read_queued_result
|
@@ -188,8 +207,8 @@ def finished(status)
|
|
188
207
|
file_list = Array.new
|
189
208
|
@success = false
|
190
209
|
end
|
191
|
-
modified = program_id.register_files(file_list)
|
192
210
|
@program_id = program_id.slice(file_list)
|
211
|
+
modified = program_id.register_files(file_list)
|
193
212
|
if !modified.empty?
|
194
213
|
needed!
|
195
214
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Autorespawn
|
2
|
+
class TrackedFile
|
3
|
+
attr_reader :path, :mtime, :size, :slaves
|
4
|
+
|
5
|
+
def initialize(path, mtime: nil, size: nil)
|
6
|
+
@path = path
|
7
|
+
@mtime = mtime
|
8
|
+
@size = size
|
9
|
+
@slaves = Array.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def update
|
13
|
+
return true if !path.exist?
|
14
|
+
return true if !mtime
|
15
|
+
|
16
|
+
stat = path.stat
|
17
|
+
if stat.mtime != mtime || stat.size != size
|
18
|
+
@mtime = stat.mtime
|
19
|
+
@size = stat.size
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/autorespawn/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autorespawn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sylvain Joyeux
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hooks
|
@@ -112,6 +112,20 @@ dependencies:
|
|
112
112
|
- - "~>"
|
113
113
|
- !ruby/object:Gem::Version
|
114
114
|
version: '2.0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: simplecov
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0.11'
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0.11'
|
115
129
|
- !ruby/object:Gem::Dependency
|
116
130
|
name: coveralls
|
117
131
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,6 +165,7 @@ files:
|
|
151
165
|
- lib/autorespawn/program_id.rb
|
152
166
|
- lib/autorespawn/self.rb
|
153
167
|
- lib/autorespawn/slave.rb
|
168
|
+
- lib/autorespawn/tracked_file.rb
|
154
169
|
- lib/autorespawn/version.rb
|
155
170
|
- lib/autorespawn/watch.rb
|
156
171
|
homepage: https://github.com/doudou/autorespawn
|