symphony 0.8.0 → 0.9.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
- 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