symphony 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -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.8.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
- HhcNMTQwMzE5MDQzNTI2WhcNMTUwMzE5MDQzNTI2WjA+MQwwCgYDVQQDDANnZWQx
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
- TuL1Bzl6TBs1YEzEubFHb9XAPgehWzzUudjDKzTRd+uyZmxnomBqTCQjT5ucNRph
28
- 3jZ6bhLNooLQxTjIuHodeGcEMHZdt4Yi7SyPmw5Nry12z6wrDp+5aGps3HsE5WsQ
29
- Zq2EuyEOc96g31uoIvjNdieKs+1kE+K+dJDjtw+wTH2i63P7r6N/NfPPXpxsFquo
30
- wcYRRrHdR7GhdJeT+V8Q8Bi5bglCUGdx+8scMgkkePc98k9osQHypbACmzO+Bqkv
31
- c7ZKPJcWBv0sm81+FCZXNACn2f9jfF8OQinxVs0O052KbGuEQaaiGIYeuuwQE2q6
32
- ggcrPfcYeTwWlfZPu2LrBg==
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: 2014-09-03 00:00:00.000000000 Z
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.1'
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.1'
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.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.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.12'
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.12'
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
- - TODO.md
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
- - TODO.md
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.2.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
@@ -1,3 +0,0 @@
1
-
2
- [ ] Per Task throttling for daemon
3
- [ ] Task scaling (min/max settings), check queue backlog during received message