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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc419ac67937b89b2a0519205e4b38b6346d73b5
4
- data.tar.gz: 29b88973f788938d4410b970778806da8b9fe7a7
3
+ metadata.gz: b81e4dd77f7397174e6174b60951b0a8e68321cb
4
+ data.tar.gz: 6768356a525a8bf86795273a333f0a9556043d4b
5
5
  SHA512:
6
- metadata.gz: 7622979c1a4afe44cded6315fda8f98c9368e98779edb7776b2c6e13c4bc9d50697fd07fff902b0bb623d9beee65917db38914416f01a1b22f2431ae7f3dcfdc
7
- data.tar.gz: b661919407a5a9f97a22bf1ce23cc79cc2073008206f187e9b4b694ef9ab7efb4c941462ffd71e5a8de529d22b41f4ea195251967f9623e293fae1bb095876de
6
+ metadata.gz: fb03843e3d1c9bcecf7c4696fd21a9964bc87d5548567159da34b54eafcd69693438f797453c45eb91fb10b65eaeec1b127bfd0ce6b0b53ba344f0e7c8edaede
7
+ data.tar.gz: 3c1d508297b1b5b1893c599e2f07371fc698455e6d70af407830be2d9313b189b8cdfe4e57c18899e3608df2b7f28af7c86ddcae5821507da2658dd01014f11b
data/examples/jobs.yml ADDED
@@ -0,0 +1,4 @@
1
+ - name: resque
2
+ command: tail -f log/production.log
3
+ env: RAILS_ENV=production, QUEUE='*'
4
+ startsecs: 1
data/examples/sv.rb ADDED
@@ -0,0 +1,3 @@
1
+ instances ({
2
+ resque: 4
3
+ })
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 :stop, :status
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
@@ -17,7 +17,7 @@ module Sv
17
17
  when "WARN"
18
18
  "#{severity.downcase.bold.yellow} #{msg}\n"
19
19
  else
20
- "#{severity.downcase.bold.blue} #{msg}\n"
20
+ "#{severity[0].upcase.bold.blue} #{msg}\n"
21
21
  end
22
22
  end
23
23
 
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
@@ -1,5 +1,5 @@
1
- [program:<%= name %>]
2
- process_name=%(program_name)s_%(process_num)02d
1
+ [program:<%= group %>]
2
+ process_name=<%= name %>_%(process_num)02d
3
3
  command=<%= command %>
4
4
  directory=<%= working_dir %>
5
5
  numprocs=<%= numprocs %>
data/lib/sv/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sv
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.7"
3
3
  end
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.5
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: 2014-11-17 00:00:00.000000000 Z
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