sv 0.0.5 → 0.0.7
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
- 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
|