breeder 0.0.1 → 0.0.2
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.
- data/VERSION +1 -1
- data/lib/breeder/breeding_strategy/forks.rb +58 -0
- data/lib/breeder/breeding_strategy/threads.rb +47 -0
- data/lib/breeder/breeding_strategy.rb +8 -0
- data/lib/breeder/core.rb +16 -32
- data/lib/breeder.rb +1 -0
- metadata +5 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Breeder
|
2
|
+
module BreedingStrategy
|
3
|
+
class Forks
|
4
|
+
|
5
|
+
def initialize(worker_factory, initial_workers)
|
6
|
+
@children = []
|
7
|
+
@worker_factory = worker_factory
|
8
|
+
@initial_workers = initial_workers
|
9
|
+
end
|
10
|
+
|
11
|
+
def start!
|
12
|
+
@initial_workers.times { spawn! }
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop!
|
16
|
+
@children.size.times { reap! }
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_worker
|
20
|
+
raise "No worker factory specified" unless !!@worker_factory
|
21
|
+
worker = @worker_factory.call
|
22
|
+
unless [:run, :stop!, :stop?].all? { |method| worker.respond_to?(method) }
|
23
|
+
raise "object from worker factory doesn't quack like a worker"
|
24
|
+
end
|
25
|
+
worker
|
26
|
+
end
|
27
|
+
|
28
|
+
def spawn!
|
29
|
+
t = Thread.new do
|
30
|
+
if pid = Process.fork
|
31
|
+
#parent
|
32
|
+
@children << pid
|
33
|
+
else
|
34
|
+
worker = create_worker
|
35
|
+
#child
|
36
|
+
trap('HUP') do
|
37
|
+
worker.stop!
|
38
|
+
end
|
39
|
+
trap('INT', 'DEFAULT')
|
40
|
+
worker.run
|
41
|
+
end
|
42
|
+
end
|
43
|
+
t.join
|
44
|
+
end
|
45
|
+
|
46
|
+
def reap!
|
47
|
+
if !@children.empty?
|
48
|
+
pid = @children.pop
|
49
|
+
Process.kill('HUP', pid)
|
50
|
+
sleep 1
|
51
|
+
Process.kill(9, pid)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Breeder
|
2
|
+
module BreedingStrategy
|
3
|
+
class Threads
|
4
|
+
|
5
|
+
def initialize(worker_factory, initial_workers)
|
6
|
+
@threads = []
|
7
|
+
@workers = []
|
8
|
+
@worker_factory = worker_factory
|
9
|
+
@initial_workers = initial_workers
|
10
|
+
end
|
11
|
+
|
12
|
+
def start!
|
13
|
+
@initial_workers.times { spawn! }
|
14
|
+
end
|
15
|
+
|
16
|
+
def stop!
|
17
|
+
@workers.size.times { reap! }
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_worker
|
21
|
+
raise "No worker factory specified" unless !!@worker_factory
|
22
|
+
worker = @worker_factory.call
|
23
|
+
unless [:run, :stop!, :stop?].all? { |method| worker.respond_to?(method) }
|
24
|
+
raise "object from worker factory doesn't quack like a worker"
|
25
|
+
end
|
26
|
+
worker
|
27
|
+
end
|
28
|
+
|
29
|
+
def spawn!
|
30
|
+
worker = create_worker
|
31
|
+
@workers << worker
|
32
|
+
@threads << Thread.new { worker.run }
|
33
|
+
end
|
34
|
+
|
35
|
+
def reap!
|
36
|
+
if !@workers.empty?
|
37
|
+
thread = @threads.pop
|
38
|
+
worker = @workers.pop
|
39
|
+
worker.stop!
|
40
|
+
sleep 1
|
41
|
+
thread.kill
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/breeder/core.rb
CHANGED
@@ -10,8 +10,6 @@ module Breeder
|
|
10
10
|
attr_accessor :initial_workers
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
@workers = []
|
14
|
-
@threads = []
|
15
13
|
self.interval = 5
|
16
14
|
self.initial_workers = 4
|
17
15
|
end
|
@@ -38,45 +36,31 @@ module Breeder
|
|
38
36
|
worker_factory { worker }
|
39
37
|
end
|
40
38
|
|
41
|
-
def
|
42
|
-
|
43
|
-
self.initial_workers.times { spawn! }
|
39
|
+
def init_strategy
|
40
|
+
@strategy = Breeder::BreedingStrategy::Forks.new(@worker_factory, initial_workers)
|
44
41
|
|
45
42
|
# catch Ctrl+C and cleanup
|
46
43
|
trap('INT') do
|
47
|
-
puts 'INTERRUPT caught, killing
|
48
|
-
@
|
44
|
+
puts 'INTERRUPT caught, killing workers and exiting...'
|
45
|
+
@strategy.stop!
|
46
|
+
@polling_thread.kill rescue nil
|
49
47
|
end
|
50
|
-
|
51
|
-
# wait for the workers to finish
|
52
|
-
@threads.each { |thread| thread.join }
|
53
48
|
end
|
54
49
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
unless [:run, :stop!, :stop?].all? { |method| worker.respond_to?(method) }
|
59
|
-
raise "object from worker factory doesn't quack like a worker"
|
60
|
-
end
|
61
|
-
worker
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
50
|
+
def run
|
51
|
+
# setup the breeding strategy
|
52
|
+
init_strategy
|
65
53
|
|
66
|
-
|
67
|
-
|
68
|
-
@workers << worker
|
69
|
-
@threads << Thread.new { worker.run }
|
70
|
-
end
|
54
|
+
# start the workers
|
55
|
+
@strategy.start!
|
71
56
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
sleep 1
|
78
|
-
thread.kill
|
57
|
+
@polling_thread = Thread.new do
|
58
|
+
# TODO polling
|
59
|
+
loop do
|
60
|
+
sleep interval
|
61
|
+
end
|
79
62
|
end
|
63
|
+
@polling_thread.join
|
80
64
|
end
|
81
65
|
|
82
66
|
end
|
data/lib/breeder.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: breeder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-10-
|
13
|
+
date: 2011-10-20 00:00:00.000000000Z
|
14
14
|
dependencies: []
|
15
15
|
description:
|
16
16
|
email:
|
@@ -28,6 +28,9 @@ files:
|
|
28
28
|
- lib/breeder/worker.rb
|
29
29
|
- lib/breeder/core.rb
|
30
30
|
- lib/breeder/watcher.rb
|
31
|
+
- lib/breeder/breeding_strategy.rb
|
32
|
+
- lib/breeder/breeding_strategy/forks.rb
|
33
|
+
- lib/breeder/breeding_strategy/threads.rb
|
31
34
|
- spec/worker_spec.rb
|
32
35
|
- spec/core_spec.rb
|
33
36
|
- spec/breeder_spec.rb
|