sv 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/jobs.yml +4 -0
- data/examples/sv.rb +3 -0
- data/lib/sv/api.rb +40 -2
- data/lib/sv/cli/server.rb +3 -1
- data/lib/sv/config.rb +9 -0
- data/lib/sv/custom_logger.rb +1 -1
- data/lib/sv/job.rb +19 -3
- data/lib/sv/rolling_restart.rb +82 -0
- data/lib/sv/server.rb +22 -0
- data/lib/sv/templates/job.erb +2 -2
- data/lib/sv/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b81e4dd77f7397174e6174b60951b0a8e68321cb
|
4
|
+
data.tar.gz: 6768356a525a8bf86795273a333f0a9556043d4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb03843e3d1c9bcecf7c4696fd21a9964bc87d5548567159da34b54eafcd69693438f797453c45eb91fb10b65eaeec1b127bfd0ce6b0b53ba344f0e7c8edaede
|
7
|
+
data.tar.gz: 3c1d508297b1b5b1893c599e2f07371fc698455e6d70af407830be2d9313b189b8cdfe4e57c18899e3608df2b7f28af7c86ddcae5821507da2658dd01014f11b
|
data/examples/jobs.yml
ADDED
data/examples/sv.rb
ADDED
data/lib/sv/api.rb
CHANGED
@@ -27,12 +27,25 @@ module Sv
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def stop_job(group, name)
|
30
|
-
call "supervisor.stopProcess" if not job_stopped?(group, name)
|
30
|
+
call "supervisor.stopProcess", "#{group}:#{name}" if not job_stopped?(group, name)
|
31
31
|
rescue XMLRPC::FaultException => e
|
32
32
|
return true if e.faultString == "NOT_RUNNING"
|
33
33
|
raise e
|
34
34
|
end
|
35
35
|
|
36
|
+
def remove_group(name)
|
37
|
+
call "supervisor.stopProcessGroup", name
|
38
|
+
call "supervisor.removeProcessGroup", name
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_group(name)
|
42
|
+
ok, output = call_safe("supervisor.addProcessGroup", name)
|
43
|
+
if not ok
|
44
|
+
msg = "adding group #{name} failed: #{output.faultString}"
|
45
|
+
raise Error, msg if not output.faultString =~ /\AALREADY_ADDED/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
36
49
|
def job_stopped?(group, name)
|
37
50
|
job = call "supervisor.getProcessInfo", "#{group}:#{name}"
|
38
51
|
job["state"] == 0 ? true : false
|
@@ -45,7 +58,7 @@ module Sv
|
|
45
58
|
def print_status
|
46
59
|
puts "pid #{pid}"
|
47
60
|
jobs = self.jobs
|
48
|
-
name_width = jobs.map { |j| j.name.size }.max
|
61
|
+
name_width = jobs.map { |j| j.name.size }.max || 20
|
49
62
|
template = "%-#{name_width}s %-10s %-7s %-20s\n"
|
50
63
|
printf template, "name", "state", "pid", "uptime"
|
51
64
|
puts "-"*(name_width + 10 + 7 + 20 + 2)
|
@@ -72,10 +85,31 @@ module Sv
|
|
72
85
|
jobs = jobs_array.map { |j| OpenStruct.new(j) }
|
73
86
|
end
|
74
87
|
|
88
|
+
def reread_config
|
89
|
+
call "supervisor.reloadConfig"
|
90
|
+
end
|
91
|
+
|
75
92
|
def close_connection
|
76
93
|
@rpc = nil
|
77
94
|
end
|
78
95
|
|
96
|
+
def reopen_logs
|
97
|
+
Process.kill("USR2", pid)
|
98
|
+
rescue => e
|
99
|
+
raise Error, "unable to reopen logs"
|
100
|
+
end
|
101
|
+
|
102
|
+
def health_check
|
103
|
+
jobs = self.jobs
|
104
|
+
not_running_jobs = jobs.reject { |j| ["RUNNING", "STARTING"].include? j.statename }
|
105
|
+
if not_running_jobs.size > 0
|
106
|
+
names = not_running_jobs.map { |j| j.name }
|
107
|
+
str = names[0..4].join(", ")
|
108
|
+
msg = "jobs not running: #{str}"
|
109
|
+
raise Error, msg
|
110
|
+
end
|
111
|
+
puts "OK"
|
112
|
+
end
|
79
113
|
|
80
114
|
private
|
81
115
|
|
@@ -92,6 +126,10 @@ module Sv
|
|
92
126
|
raise ::Sv::Error, "error running command #{args[0]}"
|
93
127
|
end
|
94
128
|
|
129
|
+
def call_safe(*args)
|
130
|
+
rpc.call2(*args)
|
131
|
+
end
|
132
|
+
|
95
133
|
def uptime(started_at)
|
96
134
|
return "-" if started_at.to_i == 0
|
97
135
|
uptime = (Time.now.to_i - started_at).to_i
|
data/lib/sv/cli/server.rb
CHANGED
@@ -19,7 +19,9 @@ module Sv::Cli
|
|
19
19
|
server.send command, auto_start: options[:auto_start], wait: options[:wait]
|
20
20
|
when :'print-config'
|
21
21
|
server.send :print_config
|
22
|
-
when :
|
22
|
+
when :rr
|
23
|
+
server.send :rolling_restart
|
24
|
+
when :stop, :status, :reopen_logs, :health_check
|
23
25
|
server.send command
|
24
26
|
when :help
|
25
27
|
help argv.shift
|
data/lib/sv/config.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'sv/logger'
|
2
2
|
require 'sv/error'
|
3
3
|
require 'sv/job'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
module Sv
|
6
7
|
class Config
|
@@ -12,6 +13,7 @@ module Sv
|
|
12
13
|
@app_dir = app_dir
|
13
14
|
@instances = {}
|
14
15
|
@working_dir = app_dir
|
16
|
+
@namespace = SecureRandom.hex(3)
|
15
17
|
end
|
16
18
|
|
17
19
|
def socket_path
|
@@ -60,6 +62,7 @@ module Sv
|
|
60
62
|
read_config("#{app_dir}/config/sv.rb")
|
61
63
|
set_instances
|
62
64
|
set_working_dir
|
65
|
+
set_namespace
|
63
66
|
end
|
64
67
|
|
65
68
|
|
@@ -75,6 +78,12 @@ module Sv
|
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
81
|
+
def set_namespace
|
82
|
+
jobs_map.each do |name, job|
|
83
|
+
job.namespace = @namespace
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
78
87
|
def read_config(path, optional: false)
|
79
88
|
if not File.readable? path
|
80
89
|
raise ::Sv::Error, "config file #{path} missing" if not optional
|
data/lib/sv/custom_logger.rb
CHANGED
data/lib/sv/job.rb
CHANGED
@@ -2,7 +2,7 @@ module Sv
|
|
2
2
|
class Job
|
3
3
|
|
4
4
|
attr_reader :name
|
5
|
-
attr_writer :working_dir
|
5
|
+
attr_writer :working_dir, :namespace
|
6
6
|
|
7
7
|
def initialize(name)
|
8
8
|
set :name, name
|
@@ -12,6 +12,10 @@ module Sv
|
|
12
12
|
attributes.fetch :name
|
13
13
|
end
|
14
14
|
|
15
|
+
def group
|
16
|
+
@namespace ? "#{name}.#{@namespace}" : name
|
17
|
+
end
|
18
|
+
|
15
19
|
def command(*args)
|
16
20
|
set_or_get :command, args
|
17
21
|
end
|
@@ -81,6 +85,18 @@ module Sv
|
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
88
|
+
def processes
|
89
|
+
processes = []
|
90
|
+
s = Struct.new(:name, :group)
|
91
|
+
numprocs.times do |i|
|
92
|
+
process = s.new
|
93
|
+
process.name = "#{name}_#{i.to_s.rjust(2,"0")}"
|
94
|
+
process.group = group
|
95
|
+
processes << process
|
96
|
+
end
|
97
|
+
processes
|
98
|
+
end
|
99
|
+
|
84
100
|
private
|
85
101
|
|
86
102
|
def attributes
|
@@ -124,16 +140,16 @@ module Sv
|
|
124
140
|
end
|
125
141
|
end
|
126
142
|
|
127
|
-
|
128
143
|
def template
|
129
144
|
@template ||= Pathname.new("#{__dir__}/templates/job.erb")
|
130
145
|
end
|
131
146
|
|
132
147
|
def binding
|
133
148
|
attrs = OpenStruct.new(attributes)
|
149
|
+
attrs.group = group
|
134
150
|
attrs.instance_eval { binding }
|
135
151
|
end
|
136
|
-
|
152
|
+
|
137
153
|
end
|
138
154
|
end
|
139
155
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'sv/logger'
|
2
|
+
module Sv
|
3
|
+
class RollingRestart
|
4
|
+
|
5
|
+
include Logger
|
6
|
+
|
7
|
+
def initialize(jobs, api)
|
8
|
+
@jobs = jobs
|
9
|
+
@api = api
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
init
|
14
|
+
@api.reread_config
|
15
|
+
stop_unneeded_processes
|
16
|
+
add_new_groups
|
17
|
+
replace_processes
|
18
|
+
remove_old_groups
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop_unneeded_processes
|
22
|
+
unneeded_processes.each do |x|
|
23
|
+
logger.info "#{"-".bold.red} #{x.name}: #{x.group}"
|
24
|
+
@api.stop_job x.group, x.name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_new_groups
|
29
|
+
@new_groups.each { |g| @api.add_group g }
|
30
|
+
end
|
31
|
+
|
32
|
+
def replace_processes
|
33
|
+
@new_processes.each do |x|
|
34
|
+
old = @old_processes.find { |p| p.name == x.name }
|
35
|
+
if old
|
36
|
+
logger.debug "stopping #{old.group}:#{old.name}"
|
37
|
+
@api.stop_job old.group, old.name
|
38
|
+
logger.info "#{"\u2219".bold.blue} #{x.name}: #{old.group} -> #{x.group}"
|
39
|
+
else
|
40
|
+
logger.info "#{"+".bold.green} #{x.name}: #{x.group}"
|
41
|
+
end
|
42
|
+
@api.start_job x.group, x.name
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def remove_old_groups
|
47
|
+
@old_groups.each { |g| @api.remove_group g }
|
48
|
+
end
|
49
|
+
|
50
|
+
def unneeded_processes
|
51
|
+
@old_processes.reject { |p| @new_processes.find {|n| n.name == p.name }}
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_old_processes
|
55
|
+
@old_processes = @api.jobs
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_old_groups
|
59
|
+
@old_groups = @old_processes.map { |p| p.group }.uniq
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_new_processes
|
63
|
+
@new_processes = []
|
64
|
+
@jobs.each do |j|
|
65
|
+
j.processes.each { |p| @new_processes << p }
|
66
|
+
end
|
67
|
+
return @new_processes
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_new_groups
|
71
|
+
@new_groups = @new_processes.map { |p| p.group }.uniq
|
72
|
+
end
|
73
|
+
|
74
|
+
def init
|
75
|
+
load_new_processes
|
76
|
+
load_new_groups
|
77
|
+
load_old_processes
|
78
|
+
load_old_groups
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/sv/server.rb
CHANGED
@@ -2,6 +2,7 @@ require 'sv/config'
|
|
2
2
|
require 'sv/api'
|
3
3
|
require 'sv/supervisor/config'
|
4
4
|
require 'sv/status'
|
5
|
+
require 'sv/rolling_restart'
|
5
6
|
|
6
7
|
module Sv
|
7
8
|
class Server
|
@@ -39,6 +40,27 @@ module Sv
|
|
39
40
|
start auto_start: auto_start, wait: wait
|
40
41
|
end
|
41
42
|
|
43
|
+
def rolling_restart
|
44
|
+
init_once
|
45
|
+
if not server_status.running?
|
46
|
+
start auto_start: true, wait: true
|
47
|
+
return
|
48
|
+
end
|
49
|
+
supervisor_config.generated_path
|
50
|
+
rolling_restart = RollingRestart.new(config.jobs, api)
|
51
|
+
rolling_restart.run
|
52
|
+
end
|
53
|
+
|
54
|
+
def reopen_logs
|
55
|
+
return if not server_status.running?
|
56
|
+
api.reopen_logs
|
57
|
+
end
|
58
|
+
|
59
|
+
def health_check
|
60
|
+
raise Error, "server not running" if not server_status.running?
|
61
|
+
api.health_check
|
62
|
+
end
|
63
|
+
|
42
64
|
def start_jobs
|
43
65
|
api.start_jobs
|
44
66
|
puts api.errors
|
data/lib/sv/templates/job.erb
CHANGED
data/lib/sv/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neeraj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,8 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
54
|
- bin/sv
|
55
|
+
- examples/jobs.yml
|
56
|
+
- examples/sv.rb
|
55
57
|
- lib/sv.rb
|
56
58
|
- lib/sv/api.rb
|
57
59
|
- lib/sv/base.rb
|
@@ -63,6 +65,7 @@ files:
|
|
63
65
|
- lib/sv/ext/string.rb
|
64
66
|
- lib/sv/job.rb
|
65
67
|
- lib/sv/logger.rb
|
68
|
+
- lib/sv/rolling_restart.rb
|
66
69
|
- lib/sv/server.rb
|
67
70
|
- lib/sv/status.rb
|
68
71
|
- lib/sv/supervisor/config.rb
|