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.
@@ -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