symphony 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +91 -3
- data/History.rdoc +13 -0
- data/Manifest.txt +10 -1
- data/README.rdoc +1 -1
- data/Rakefile +5 -5
- data/UPGRADING.md +38 -0
- data/USAGE.rdoc +1 -1
- data/lib/symphony.rb +86 -5
- data/lib/symphony/daemon.rb +94 -147
- data/lib/symphony/queue.rb +11 -4
- data/lib/symphony/routing.rb +5 -4
- data/lib/symphony/signal_handling.rb +1 -2
- data/lib/symphony/statistics.rb +96 -0
- data/lib/symphony/task.rb +71 -11
- data/lib/symphony/task_group.rb +165 -0
- data/lib/symphony/task_group/longlived.rb +98 -0
- data/lib/symphony/task_group/oneshot.rb +25 -0
- data/lib/symphony/tasks/oneshot_simulator.rb +61 -0
- data/lib/symphony/tasks/simulator.rb +22 -18
- data/spec/helpers.rb +67 -1
- data/spec/symphony/daemon_spec.rb +83 -31
- data/spec/symphony/queue_spec.rb +2 -2
- data/spec/symphony/routing_spec.rb +297 -0
- data/spec/symphony/statistics_spec.rb +71 -0
- data/spec/symphony/task_group/longlived_spec.rb +219 -0
- data/spec/symphony/task_group/oneshot_spec.rb +56 -0
- data/spec/symphony/task_group_spec.rb +93 -0
- data/spec/symphony_spec.rb +6 -0
- metadata +41 -18
- metadata.gz.sig +0 -0
- data/TODO.md +0 -3
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../../helpers'
|
4
|
+
|
5
|
+
require 'symphony/task_group/oneshot'
|
6
|
+
|
7
|
+
|
8
|
+
describe Symphony::TaskGroup::Oneshot do
|
9
|
+
|
10
|
+
let( :task ) do
|
11
|
+
Class.new( Symphony::Task ) do
|
12
|
+
extend Symphony::MethodUtilities
|
13
|
+
|
14
|
+
singleton_attr_accessor :has_before_forked, :has_after_forked, :has_run
|
15
|
+
|
16
|
+
def self::before_fork
|
17
|
+
self.has_before_forked = true
|
18
|
+
end
|
19
|
+
def self::after_fork
|
20
|
+
self.has_after_forked = true
|
21
|
+
end
|
22
|
+
def self::run
|
23
|
+
self.has_run = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let( :task_group ) do
|
29
|
+
described_class.new( task, 2 )
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
it "starts workers for each of its worker slots" do
|
34
|
+
allow( Process ).to receive( :setpgid )
|
35
|
+
expect( Process ).to receive( :fork ).and_return( 11, 22 )
|
36
|
+
expect( task_group.adjust_workers ).to eq([ 11, 22 ])
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
it "doesn't start workers if the max number of workers are already started" do
|
41
|
+
expect( Process ).to_not receive( :fork )
|
42
|
+
task_group.workers << 11 << 22
|
43
|
+
expect( task_group.adjust_workers ).to be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
it "doesn't start anything if it's throttled" do
|
48
|
+
# Simulate a child starting up and failing
|
49
|
+
task_group.instance_variable_set( :@last_child_started, Time.now )
|
50
|
+
task_group.adjust_throttle( 5 )
|
51
|
+
|
52
|
+
expect( Process ).to_not receive( :fork )
|
53
|
+
expect( task_group.adjust_workers ).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../helpers'
|
4
|
+
|
5
|
+
describe Symphony::TaskGroup do
|
6
|
+
|
7
|
+
let( :task ) do
|
8
|
+
Class.new( Symphony::Task ) do
|
9
|
+
extend Symphony::MethodUtilities
|
10
|
+
|
11
|
+
singleton_attr_accessor :has_before_forked, :has_after_forked, :has_run
|
12
|
+
|
13
|
+
def self::before_fork
|
14
|
+
self.has_before_forked = true
|
15
|
+
end
|
16
|
+
def self::after_fork
|
17
|
+
self.has_after_forked = true
|
18
|
+
end
|
19
|
+
def self::run( * )
|
20
|
+
self.has_run = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
let( :task_group ) { described_class.new(task, 2) }
|
26
|
+
|
27
|
+
|
28
|
+
it "can start and stop workers for its task" do
|
29
|
+
pid = 17
|
30
|
+
|
31
|
+
expect( task_group.workers ).to be_empty
|
32
|
+
|
33
|
+
expect( Process ).to receive( :fork ) do |*args, &block|
|
34
|
+
block.call
|
35
|
+
pid
|
36
|
+
end
|
37
|
+
expect( Process ).to receive( :setpgid ).with( pid, 0 )
|
38
|
+
task_group.start_worker
|
39
|
+
|
40
|
+
expect( task_group.workers ).to_not be_empty
|
41
|
+
expect( task_group.workers.size ).to eq( 1 )
|
42
|
+
expect( task_group.workers.first ).to eq( pid )
|
43
|
+
|
44
|
+
expect( Process ).to receive( :kill ).with( :TERM, task_group.workers.first )
|
45
|
+
task_group.stop_worker
|
46
|
+
|
47
|
+
status = double( Process::Status, :success? => true )
|
48
|
+
task_group.on_child_exit( pid, status )
|
49
|
+
expect( task_group.workers ).to be_empty
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
it "can stop all of its workers" do
|
54
|
+
task_group.workers << 11 << 22 << 33 << 44
|
55
|
+
expect( Process ).to receive( :kill ).with( :TERM, 11 )
|
56
|
+
expect( Process ).to receive( :kill ).with( :TERM, 22 )
|
57
|
+
expect( Process ).to receive( :kill ).with( :TERM, 33 )
|
58
|
+
expect( Process ).to receive( :kill ).with( :TERM, 44 )
|
59
|
+
task_group.stop_all_workers
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
it "can restart all of its workers" do
|
64
|
+
task_group.workers << 11 << 22 << 33 << 44
|
65
|
+
expect( Process ).to receive( :kill ).with( :HUP, 11 )
|
66
|
+
expect( Process ).to receive( :kill ).with( :HUP, 22 )
|
67
|
+
expect( Process ).to receive( :kill ).with( :HUP, 33 )
|
68
|
+
expect( Process ).to receive( :kill ).with( :HUP, 44 )
|
69
|
+
task_group.restart_workers
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
it "requires its concrete derivatives to overload #adjust_workers" do
|
74
|
+
expect {
|
75
|
+
task_group.adjust_workers
|
76
|
+
}.to raise_error( NotImplementedError, /needs to provide/i )
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
it "provides a mechanism for throttling task startups" do
|
81
|
+
expect( task_group ).to_not be_throttled
|
82
|
+
expect( task_group.throttle_seconds ).to eq( 0 )
|
83
|
+
|
84
|
+
# Simulate a child starting up and failing
|
85
|
+
task_group.instance_variable_set( :@last_child_started, Time.now )
|
86
|
+
task_group.adjust_throttle( 5 )
|
87
|
+
|
88
|
+
expect( task_group ).to be_throttled
|
89
|
+
expect( task_group.throttle_seconds ).to be > 0
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
data/spec/symphony_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe Symphony do
|
|
10
10
|
|
11
11
|
before( :each ) do
|
12
12
|
ENV.delete( 'SYMPHONY_CONFIG' )
|
13
|
+
Symphony.configure( tasks: ['test', 'test'] )
|
13
14
|
end
|
14
15
|
|
15
16
|
|
@@ -65,5 +66,10 @@ describe Symphony do
|
|
65
66
|
described_class.load_config( 'a/different/configfile.yml', database: {dbname: 'test'} )
|
66
67
|
end
|
67
68
|
|
69
|
+
it "loads a task class for each configured task" do
|
70
|
+
expect( Symphony.tasks.size ).to eq( 1 )
|
71
|
+
expect( Symphony.tasks ).to include( Symphony::SpecHelpers::TestTask )
|
72
|
+
end
|
73
|
+
|
68
74
|
end
|
69
75
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -13,7 +13,7 @@ cert_chain:
|
|
13
13
|
-----BEGIN CERTIFICATE-----
|
14
14
|
MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANnZWQx
|
15
15
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
16
|
-
|
16
|
+
HhcNMTUwNDAxMjEyNDEzWhcNMTYwMzMxMjEyNDEzWjA+MQwwCgYDVQQDDANnZWQx
|
17
17
|
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
18
18
|
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb92mkyYwuGBg1oRxt2tkH
|
19
19
|
+Uo3LAsaL/APBfSLzy8o3+B3AUHKCjMUaVeBoZdWtMHB75X3VQlvXfZMyBxj59Vo
|
@@ -24,14 +24,14 @@ cert_chain:
|
|
24
24
|
AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSZ0hCV
|
25
25
|
qoHr122fGKelqffzEQBhszAcBgNVHREEFTATgRFnZWRARmFlcmllTVVELm9yZzAc
|
26
26
|
BgNVHRIEFTATgRFnZWRARmFlcmllTVVELm9yZzANBgkqhkiG9w0BAQUFAAOCAQEA
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
lUKo3NXePpuvN3QGsOLJ6QhNd4+Q9Rz75GipuMrCl296V8QFkd2gg9EG44Pqtk+9
|
28
|
+
Zac8TkKc9bCSR0snakp+cCPplVvZF0/gMzkSTUJkDBHlNV16z73CyWpbQQa+iLJ4
|
29
|
+
uisI6gF2ZXK919MYLn2bFJfb7OsCvVfyTPqq8afPY+rq9vlf9ZPwU49AlD8bPRic
|
30
|
+
0LX0gO5ykvETIOv+WgGcqp96ceNi9XVuJMh20uWuw6pmv/Ub2RqAf82jQSbpz09G
|
31
|
+
G8LHR7EjtPPmqCCunfyecJ6MmCNaiJCBxq2NYzyNmluPyHT8+0fuB5kccUVZm6CD
|
32
|
+
xn3DzOkDE6NYbk8gC9rTsA==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date:
|
34
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: configurability
|
@@ -39,14 +39,14 @@ dependencies:
|
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '2.
|
42
|
+
version: '2.2'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '2.
|
49
|
+
version: '2.2'
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: loggability
|
52
52
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,14 +81,14 @@ dependencies:
|
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: '1.
|
84
|
+
version: '1.5'
|
85
85
|
type: :runtime
|
86
86
|
prerelease: false
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: '1.
|
91
|
+
version: '1.5'
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: sysexits
|
94
94
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,20 +243,34 @@ dependencies:
|
|
243
243
|
- - "~>"
|
244
244
|
- !ruby/object:Gem::Version
|
245
245
|
version: '0.8'
|
246
|
+
- !ruby/object:Gem::Dependency
|
247
|
+
name: timecop
|
248
|
+
requirement: !ruby/object:Gem::Requirement
|
249
|
+
requirements:
|
250
|
+
- - "~>"
|
251
|
+
- !ruby/object:Gem::Version
|
252
|
+
version: '0.7'
|
253
|
+
type: :development
|
254
|
+
prerelease: false
|
255
|
+
version_requirements: !ruby/object:Gem::Requirement
|
256
|
+
requirements:
|
257
|
+
- - "~>"
|
258
|
+
- !ruby/object:Gem::Version
|
259
|
+
version: '0.7'
|
246
260
|
- !ruby/object:Gem::Dependency
|
247
261
|
name: hoe
|
248
262
|
requirement: !ruby/object:Gem::Requirement
|
249
263
|
requirements:
|
250
264
|
- - "~>"
|
251
265
|
- !ruby/object:Gem::Version
|
252
|
-
version: '3.
|
266
|
+
version: '3.13'
|
253
267
|
type: :development
|
254
268
|
prerelease: false
|
255
269
|
version_requirements: !ruby/object:Gem::Requirement
|
256
270
|
requirements:
|
257
271
|
- - "~>"
|
258
272
|
- !ruby/object:Gem::Version
|
259
|
-
version: '3.
|
273
|
+
version: '3.13'
|
260
274
|
description: |-
|
261
275
|
Symphony is a subscription-based asynchronous job system. It
|
262
276
|
allows you to define jobs that watch for lightweight events from a
|
@@ -282,7 +296,7 @@ extra_rdoc_files:
|
|
282
296
|
- History.rdoc
|
283
297
|
- Manifest.txt
|
284
298
|
- README.rdoc
|
285
|
-
-
|
299
|
+
- UPGRADING.md
|
286
300
|
- USAGE.rdoc
|
287
301
|
files:
|
288
302
|
- ".simplecov"
|
@@ -291,7 +305,7 @@ files:
|
|
291
305
|
- Manifest.txt
|
292
306
|
- README.rdoc
|
293
307
|
- Rakefile
|
294
|
-
-
|
308
|
+
- UPGRADING.md
|
295
309
|
- USAGE.rdoc
|
296
310
|
- bin/symphony
|
297
311
|
- bin/symphony-task
|
@@ -303,15 +317,24 @@ files:
|
|
303
317
|
- lib/symphony/queue.rb
|
304
318
|
- lib/symphony/routing.rb
|
305
319
|
- lib/symphony/signal_handling.rb
|
320
|
+
- lib/symphony/statistics.rb
|
306
321
|
- lib/symphony/task.rb
|
322
|
+
- lib/symphony/task_group.rb
|
323
|
+
- lib/symphony/task_group/longlived.rb
|
324
|
+
- lib/symphony/task_group/oneshot.rb
|
307
325
|
- lib/symphony/tasks/auditor.rb
|
308
326
|
- lib/symphony/tasks/failure_logger.rb
|
327
|
+
- lib/symphony/tasks/oneshot_simulator.rb
|
309
328
|
- lib/symphony/tasks/simulator.rb
|
310
329
|
- spec/helpers.rb
|
311
330
|
- spec/symphony/daemon_spec.rb
|
312
331
|
- spec/symphony/mixins_spec.rb
|
313
332
|
- spec/symphony/queue_spec.rb
|
314
333
|
- spec/symphony/routing_spec.rb
|
334
|
+
- spec/symphony/statistics_spec.rb
|
335
|
+
- spec/symphony/task_group/longlived_spec.rb
|
336
|
+
- spec/symphony/task_group/oneshot_spec.rb
|
337
|
+
- spec/symphony/task_group_spec.rb
|
315
338
|
- spec/symphony/task_spec.rb
|
316
339
|
- spec/symphony_spec.rb
|
317
340
|
homepage: http://bitbucket.org/ged/symphony
|
@@ -338,7 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
338
361
|
version: 2.0.3
|
339
362
|
requirements: []
|
340
363
|
rubyforge_project:
|
341
|
-
rubygems_version: 2.
|
364
|
+
rubygems_version: 2.4.6
|
342
365
|
signing_key:
|
343
366
|
specification_version: 4
|
344
367
|
summary: Symphony is a subscription-based asynchronous job system
|
metadata.gz.sig
CHANGED
Binary file
|
data/TODO.md
DELETED