uc 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f34804e8f79d78729380eeab1d954bee634792ad
4
- data.tar.gz: 327501a9ea5089ea852ab3f1907485f48422cc22
3
+ metadata.gz: 59c522f2247a747ec300e7cafbd827b7700f18be
4
+ data.tar.gz: 7303d81d3893d08bed3de0856835014df3882efe
5
5
  SHA512:
6
- metadata.gz: bdea49006e4b025300bd0cb94e7577b5b40f492bf536252ee77f051505b208ad6a1151e30a125713d00a7f8d2d984ec5bbd02cd4d43489236c20e523c9d75ae2
7
- data.tar.gz: 49f24b6ce3d7017db4d2a5822a1b3b63f0310ce28d6ef148e49f40b55b8911c520b83fe1978b6b8b48400e1f3e9f4088a0da0fe47681d55061a82cd0b8a5b4d1
6
+ metadata.gz: 7bda91add1413b1fa20739eaf23b975d45920e8dd8739fce7d2d7de97db8ba1b18d9762337ced2c796203882d2a188e29dececa291e93d1ef2df7e9a31489f03
7
+ data.tar.gz: e9764c28553b46752e4d1c0689ca93a5aed0e601c0c7d3e38a531d434ee3159e66fa12c690ebb3b8bcf41cb18960d35e8b37caaededa8898c99c525b2f1f6bc1
data/bin/uc CHANGED
@@ -8,7 +8,10 @@ require 'optparse'
8
8
  require 'uc/error'
9
9
  require 'uc/version'
10
10
  require 'uc/server'
11
+ require 'uc/logger'
12
+ require 'uc/lock'
11
13
 
14
+ logger = ::Uc::Logger.logger
12
15
  options = {}
13
16
  options[:rails_env] = "production"
14
17
 
@@ -38,6 +41,11 @@ opts_parser = OptionParser.new do |opts|
38
41
  exit
39
42
  end
40
43
 
44
+ opts.on("--debug", "Show debug messages") do
45
+ logger.level = ::Logger::DEBUG
46
+ ENV["UC_DEBUG"] = "true"
47
+ end
48
+
41
49
  opts.on_tail("-h", "--help", "Show this message") do
42
50
  puts opts
43
51
  exit
@@ -46,8 +54,9 @@ end
46
54
 
47
55
  begin
48
56
  opts_parser.parse!(ARGV)
49
-
50
57
  app_dir = options[:app_dir] || Dir.pwd
58
+ lock = ::Uc::Lock.new(app_dir)
59
+ lock.acquire
51
60
  server = ::Uc::Server.new(app_dir, rails_env: options[:rails_env])
52
61
  command = ARGV.shift
53
62
 
@@ -55,14 +64,14 @@ begin
55
64
  when "start", "stop", "restart", "status"
56
65
  server.send command.to_sym
57
66
  when "rr", "rolling-restart"
58
- server.rolling_restart ARGV.shift
67
+ server.rolling_restart
59
68
  when nil
60
- puts "ERROR No command specified",""
69
+ logger.error "No command specified"
61
70
  puts opts_parser
62
71
  abort
63
72
  end
64
73
 
65
74
  rescue OptionParser::InvalidOption, OptionParser::MissingArgument, ::Uc::Error => e
66
- puts "ERROR #{e.message}"
75
+ logger.error "#{e.message}"
67
76
  abort
68
77
  end
data/lib/uc/lock.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'uc/error'
2
+ module Uc
3
+ class Lock
4
+
5
+ attr_reader :app_dir
6
+ def initialize(app_dir)
7
+ @app_dir = app_dir
8
+ end
9
+
10
+ def acquire
11
+ Dir.chdir app_dir do
12
+ lock_acquired = File.new("tmp/.uc.lock", "a+").flock( File::LOCK_NB | File::LOCK_EX )
13
+ raise ::Uc::Error,"another uc process is already running" if not lock_acquired
14
+ end
15
+ end
16
+
17
+ end
18
+ end
data/lib/uc/logger.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'logger'
2
+ require 'uc/mq_logger'
2
3
  module Uc
3
4
  module Logger
4
5
 
@@ -6,16 +7,26 @@ module Uc
6
7
  @logger ||= begin
7
8
  logger = ::Logger.new(STDOUT)
8
9
  logger.formatter = proc do |severity, datetime, progname, msg|
9
- "#{msg}\n"
10
+ if severity == "INFO"
11
+ "#{msg}\n"
12
+ else
13
+ "#{severity} #{msg}\n"
14
+ end
10
15
  end
11
16
  logger.level = ::Logger::INFO
12
17
  logger
13
18
  end
14
- end
19
+ end
15
20
 
16
21
  def logger
17
22
  ::Uc::Logger.logger
18
23
  end
19
24
 
25
+ def mq_log(msg)
26
+ return if not respond_to? :queue_name
27
+ @mq_logger ||= ::Uc::MqLogger.new(queue_name)
28
+ @mq_logger.log msg
29
+ end
30
+
20
31
  end
21
32
  end
@@ -0,0 +1,22 @@
1
+ module Uc
2
+ class MqLogger
3
+
4
+ attr_reader :queue_name
5
+
6
+ def initialize(queue_name)
7
+ @queue_name = queue_name
8
+ end
9
+
10
+ def mq
11
+ @mq ||= ::Uc::Mqueue.new(queue_name)
12
+ end
13
+
14
+ def log(msg)
15
+ @writer ||= mq.nb_writer
16
+ @writer.send msg
17
+ rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES, Errno::EMSGSIZE => e
18
+ puts "#{e.class} #{e.message}"
19
+ end
20
+
21
+ end
22
+ end
data/lib/uc/mqueue.rb CHANGED
@@ -1,66 +1,84 @@
1
1
  require 'posix_mq'
2
- require 'uc/logger'
3
2
  module Uc
4
3
  class Mqueue
5
- include ::Uc::Logger
6
4
 
7
- attr_reader :name
5
+ attr_reader :name, :max_msg, :msg_size
8
6
 
9
- def initialize(name)
7
+ def initialize(name, max_msg: 10, msg_size: 100)
10
8
  @name = name
9
+ @max_msg = max_msg
10
+ @msg_size = msg_size
11
11
  end
12
12
 
13
- def setup
14
- attr = ::POSIX_MQ::Attr.new(0,100,100) # o_readonly, maxmsg, msgsize
15
- puts name
13
+ def create
16
14
  ::POSIX_MQ.new("/#{name}", :rw, 0700, attr)
17
- make_empty
18
15
  end
19
16
 
20
- def reader
21
- @reader ||= ::POSIX_MQ.new("/#{name}", :r)
17
+ def recreate
18
+ destroy
19
+ create
22
20
  end
23
21
 
24
- def nb_reader
25
- mq = ::POSIX_MQ.new("/#{name}", :r)
26
- mq.nonblock = true
27
- return mq
22
+ def destroy
23
+ ::POSIX_MQ.unlink("/#{name}")
24
+ rescue
25
+ return false
28
26
  end
29
27
 
30
- def writer
31
- POSIX_MQ.new("/#{name}", IO::WRONLY)
28
+ def attr
29
+ ::POSIX_MQ::Attr.new(0,max_msg,msg_size)
30
+ end
31
+
32
+ def new_mq(io_mode, nonblock, &block)
33
+ mq = ::POSIX_MQ.new("/#{name}", io_mode)
34
+ mq.nonblock = true if nonblock
35
+ return mq if not block_given?
36
+
37
+ begin
38
+ yield mq
39
+ ensure
40
+ mq.close if mq
41
+ end
32
42
  end
33
43
 
34
- def nb_writer
35
- writer = POSIX_MQ.new("/#{name}", IO::WRONLY)
36
- writer.nonblock = true
37
- return writer
44
+ def reader(&block)
45
+ new_mq(:r, false, &block)
38
46
  end
39
47
 
40
- def watch(loglevel: :info, msg: "success", err_msg: "error", &block)
41
- setup
42
- make_empty
43
- yield
44
- wait_for_fin(msg, err_msg, loglevel)
48
+ def nb_reader(&block)
49
+ new_mq(:r, true, &block)
50
+ end
51
+
52
+ def writer(&block)
53
+ new_mq(IO::WRONLY, false, &block)
45
54
  end
46
55
 
47
- def wait_for_fin(msg, err_msg, loglevel)
56
+ def nb_writer(&block)
57
+ new_mq(IO::WRONLY, true, &block)
58
+ end
59
+
60
+ def wait(event, timeout, output: false)
61
+ event = event.to_s
48
62
  message = ""
49
- timeout = 30
50
- while message != "fin"
51
- reader.receive(message, timeout)
52
- logger.send(loglevel, message) if message != "fin"
63
+ reader do |r|
64
+ while message != event do
65
+ r.receive(message, timeout)
66
+ puts "> #{message}" if output
67
+ end
53
68
  end
54
- logger.info msg
55
- rescue Errno::ETIMEDOUT
56
- logger.info "#{timeout}s timeout reached while waiting for message"
57
- raise ::Uc::Error, err_msg
69
+ return message
70
+ end
71
+
72
+ def watch(event, timeout: 30, recreate: true, &block)
73
+ self.recreate if recreate
74
+ clear
75
+ yield
76
+ wait(event, timeout, output: true)
58
77
  end
59
78
 
60
- def make_empty
61
- mq = nb_reader
62
- while true do
63
- mq.receive
79
+ def clear
80
+ nb_reader do |mq|
81
+ loop { mq.receive }
64
82
  end
65
83
  rescue Errno::EAGAIN
66
84
  return
data/lib/uc/server.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require 'uc/logger'
2
2
  require 'uc/shell_helper'
3
3
  require 'uc/mqueue'
4
- require 'uc/unicorn'
5
- require 'uc/unicorn_config'
4
+ require 'uc/unicorn/api'
5
+ require 'uc/unicorn/config'
6
6
  require 'uc/error'
7
7
 
8
8
  module Uc
9
+
9
10
  class Server
10
11
 
11
12
  include ::Uc::ShellHelper
@@ -15,9 +16,9 @@ module Uc
15
16
  attr_reader :rails_env
16
17
 
17
18
  def initialize(app_dir, rails_env: "production")
18
- @uconfig = ::Uc::UnicornConfig.new(app_dir)
19
+ @uconfig = ::Uc::Unicorn::Config.new(app_dir)
19
20
  @rails_env = rails_env
20
- load_env
21
+ @uconfig.load_env
21
22
  end
22
23
 
23
24
  def app_env(&block)
@@ -48,21 +49,6 @@ module Uc
48
49
  end
49
50
  end
50
51
 
51
- def kill(pid, timeout)
52
- Process.kill(:TERM, pid)
53
- logger.debug "TERM signal sent to #{pid}"
54
- (1..timeout).each do
55
- if not process_running? pid
56
- logger.info "Stopped #{pid}"
57
- return
58
- end
59
- sleep 1
60
- end
61
- Process.kill(9, pid)
62
- sleep 1
63
- logger.info "Killed #{pid}"
64
- end
65
-
66
52
  def status
67
53
  status = ( server_running? ? "Running pid #{pid}" : "Stopped")
68
54
  puts status
@@ -73,20 +59,44 @@ module Uc
73
59
  start
74
60
  end
75
61
 
76
- def rolling_restart(queue = nil)
62
+ def rolling_restart
77
63
  app_env
78
64
  if not server_running?
79
65
  start
80
66
  return
81
67
  end
82
- queue ||= get_queue_name
83
- raise ::Uc::Error, "argument missing mq name" if (queue.nil? || queue.empty?)
84
- mq = ::Uc::Mqueue.new(queue)
85
- mq.watch err_msg: "server may not have restarted successfully" do
86
- Process.kill("USR2", pid)
68
+ mq = ::Uc::Mqueue.new(queue_name)
69
+ begin
70
+ mq.watch :fin do
71
+ Process.kill("USR2", pid)
72
+ end
73
+ rescue Errno::EACCES
74
+ raise ::Uc::Error, "unable to setup message queue"
75
+ rescue Errno::ENOENT
76
+ raise ::Uc::Error, "message queue deleted"
77
+ rescue Errno::ETIMEDOUT
78
+ raise ::Uc::Error, "timeout reached while waiting for server to restart"
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def kill(pid, timeout)
85
+ Process.kill(:TERM, pid)
86
+ logger.debug "TERM signal sent to #{pid}"
87
+ (1..timeout).each do
88
+ if not process_running? pid
89
+ logger.info "Stopped #{pid}"
90
+ return
91
+ end
92
+ sleep 1
87
93
  end
94
+ Process.kill(9, pid)
95
+ sleep 1
96
+ logger.info "Killed #{pid}"
88
97
  end
89
98
 
99
+
90
100
  def process_running?(pid)
91
101
  return false if pid <= 0
92
102
  Process.getpgid pid
@@ -99,25 +109,15 @@ module Uc
99
109
  process_running? pid
100
110
  end
101
111
 
102
- def get_queue_name
103
- Dir.chdir uconfig.app_dir do
104
- return ::Uc::Unicorn.get_queue_name
105
- end
106
- end
107
-
108
- def read_pid
109
- uconfig.read_pid
110
- end
111
-
112
112
  def pid
113
- @pid ||= read_pid
113
+ uconfig.pid
114
114
  end
115
115
 
116
- def load_env
117
- env_file = "#{uconfig.app_dir}/config/uc_env.rb"
118
- File.readable? env_file and
119
- load "#{uconfig.app_dir}/config/uc_env.rb"
120
- rescue LoadError
116
+ def queue_name
117
+ @queue_name ||= Dir.chdir uconfig.app_dir do
118
+ api = ::Uc::Unicorn::Api.new
119
+ api.queue_name
120
+ end
121
121
  end
122
122
 
123
123
  end
@@ -0,0 +1,60 @@
1
+ require 'uc/unicorn/rolling_restart'
2
+ require 'uc/unicorn/prestart'
3
+ require 'securerandom'
4
+
5
+ module Uc; module Unicorn
6
+
7
+ class Api
8
+
9
+ attr_reader :run_id
10
+
11
+ def initialize
12
+ @run_id = SecureRandom.hex(3)
13
+ end
14
+
15
+ def rolling_restart(server, worker, **kwargs)
16
+ rolling_restart = ::Uc::Unicorn::RollingRestart.new(server, worker, queue_name, **kwargs)
17
+ rolling_restart.run_id = @run_id
18
+ rolling_restart.run
19
+ end
20
+
21
+
22
+ def prestart(server, worker, **kwargs)
23
+ prestart = ::Uc::Unicorn::Prestart.new(server, worker, queue_name, **kwargs)
24
+ prestart.run_id = @run_id
25
+ prestart.run
26
+ end
27
+
28
+ def clean_env
29
+ ENV.delete "BUNDLE_BIN_PATH"
30
+ ENV.delete "RUBYLIB"
31
+ ENV.delete "RUBYOPT"
32
+ ENV.delete "GEM_HOME"
33
+ ENV.delete "GEM_PATH"
34
+ end
35
+
36
+ def queue_name
37
+ @queue_name ||= begin
38
+ queue_name_from_file || "unicorn_#{Process.uid}"
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def queue_name_from_file
45
+ queue_file = Pathname.new queue_name_file
46
+ queue_name = nil
47
+ if queue_file.readable?
48
+ queue_name = File.read(queue_file).chomp
49
+ queue_name = (queue_name.empty? ? nil : queue_name)
50
+ end
51
+ return queue_name
52
+ end
53
+
54
+ def queue_name_file
55
+ "config/unicorn_mq"
56
+ end
57
+
58
+ end
59
+
60
+ end; end
@@ -1,7 +1,7 @@
1
1
  require 'pathname'
2
2
  require 'uc/logger'
3
- module Uc
4
- class UnicornConfig
3
+ module Uc; module Unicorn
4
+ class Config
5
5
 
6
6
  include ::Uc::Logger
7
7
 
@@ -43,6 +43,10 @@ module Uc
43
43
  return -1
44
44
  end
45
45
 
46
+ def pid
47
+ @pid ||= read_pid
48
+ end
49
+
46
50
  def check_dirs
47
51
  logger.debug "Using app_dir => #{app_dir}"
48
52
  raise ::Uc::Error, %{app_dir not readable} if not path_readable? app_dir
@@ -57,6 +61,12 @@ module Uc
57
61
  @dirs_checked
58
62
  end
59
63
 
64
+ def load_env
65
+ env_file = rpath "config/uc_env.rb"
66
+ File.readable? env_file and
67
+ load env_file
68
+ rescue LoadError
69
+ end
60
70
 
61
71
  private
62
72
 
@@ -66,14 +76,11 @@ module Uc
66
76
  "#{app_dir}/#{path}"
67
77
  end
68
78
 
69
- def rpathname(path)
70
- Pathname.new(rpath(path))
71
- end
72
-
73
79
  def path_readable?(path_str)
74
80
  path = Pathname.new(path_str)
75
81
  path.readable?
76
82
  end
77
83
 
84
+
78
85
  end
79
- end
86
+ end; end
@@ -0,0 +1,83 @@
1
+ require 'uc/logger'
2
+ require 'uc/mqueue'
3
+
4
+ module Uc; module Unicorn;
5
+ class Prestart
6
+
7
+ include ::Uc::Logger
8
+
9
+ attr_reader :server, :worker, :queue_name, :url
10
+ attr_accessor :run_id
11
+
12
+ def initialize(server, worker, queue_name, url: "/", run_id: nil)
13
+ @server = server
14
+ @worker = worker
15
+ @url = url
16
+ @queue_name = queue_name
17
+ @run_id = run_id
18
+ end
19
+
20
+ def app
21
+ @app ||= server.instance_variable_get("@app")
22
+ end
23
+
24
+ def run
25
+ response = app.call(rack_request)
26
+ body = response[2]
27
+ body.close
28
+ end_prestart
29
+ rescue => e
30
+ logger.warn "pre start failed for worker : #{e.message}"
31
+ end
32
+
33
+
34
+ private
35
+
36
+ def worker_id
37
+ worker.nr + 1
38
+ end
39
+
40
+ def rack_request
41
+ Rack::MockRequest.env_for("http://127.0.0.1/#{url}")
42
+ end
43
+
44
+ def last_worker?
45
+ (worker.nr + 1) == server.worker_processes
46
+ end
47
+
48
+ def end_prestart
49
+ if last_worker?
50
+ logger.debug "[ps] no_event #{worker_id}"
51
+ return
52
+ end
53
+ logger.debug "[ps] start #{worker_id}"
54
+ send_prestart_end
55
+ mq_log "prestart end worker #{worker_id}"
56
+ logger.debug "[ps] end #{worker_id}"
57
+ end
58
+
59
+ def send_prestart_end
60
+ mq.create
61
+ mq.clear
62
+ mq.nb_writer do |writer|
63
+ writer.send prestart_end_event
64
+ end
65
+ rescue Errno::ENOENT, Errno::EAGAIN, Errno::EACCES => e
66
+ logger.warn "prestart failed for worker #{worker.nr + 1}: #{e.class}"
67
+ end
68
+
69
+ def prestart_end_event
70
+ run_id ? "prestart_end_#{run_id}" : "prestart_end"
71
+ end
72
+
73
+ def mq
74
+ @mq ||= ::Uc::Mqueue.new(prestart_queue_name, max_msg: 10, msg_size: 30)
75
+ end
76
+
77
+ def prestart_queue_name
78
+ "#{queue_name}_prestart_#{worker.nr}"
79
+ end
80
+
81
+ end
82
+ end; end
83
+
@@ -0,0 +1,87 @@
1
+ require 'uc/mqueue'
2
+ require 'uc/logger'
3
+ module Uc; module Unicorn
4
+ class RollingRestart
5
+
6
+ include ::Uc::Logger
7
+ attr_reader :server, :worker, :queue_name, :prestart_wait, :sleep_secs
8
+ attr_accessor :run_id
9
+
10
+ def initialize(server, worker, queue_name, prestart_wait: nil, sleep_secs: 0.1)
11
+ @server = server
12
+ @worker = worker
13
+ @queue_name = queue_name
14
+ @prestart_wait = prestart_wait
15
+ @sleep_secs = sleep_secs
16
+ end
17
+
18
+ def run
19
+ return if not (server && worker)
20
+ return if not restart?
21
+
22
+ destroy_prestart_queues
23
+ wait_for_prestart_end_event
24
+ sleep sleep_secs if not first_worker?
25
+ kill_old_worker
26
+ end
27
+
28
+ private
29
+
30
+ def prestart_mq
31
+ @prestart_mq ||= ::Uc::Mqueue.new(prestart_queue, max_msg: 10, msg_size: 30)
32
+ end
33
+
34
+ def destroy_prestart_queues
35
+ return if not first_worker?
36
+ (0..server.worker_processes).each do |i|
37
+ mq = ::Uc::Mqueue.new("#{queue_name}_prestart_#{i}")
38
+ mq.destroy
39
+ end
40
+ end
41
+
42
+ def prestart_queue
43
+ first_worker? ? nil : "#{queue_name}_prestart_#{worker.nr - 1}"
44
+ end
45
+
46
+ def wait_for_prestart_end_event
47
+ return if not prestart_wait
48
+ if not prestart_queue
49
+ logger.debug "[rr] no ps wait for #{worker.nr + 1}"
50
+ return
51
+ end
52
+ begin
53
+ prestart_mq.create
54
+ msg = prestart_mq.wait( prestart_end_event, prestart_wait)
55
+ logger.debug "[rr] ps end event #{prestart_end_event} for #{ worker.nr + 1}"
56
+ rescue => e
57
+ logger.info "#{e.class} #{e.message}"
58
+ end
59
+ end
60
+
61
+ def kill_old_worker
62
+ sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
63
+ Process.kill(sig, File.read(old_pid).to_i)
64
+ mq_log "starting worker #{worker.nr + 1}"
65
+ mq_log "fin" if sig == :QUIT
66
+ rescue Errno::ENOENT, Errno::ESRCH, Errno::EAGAIN, Errno::EACCES => e
67
+ logger.error "rolling restart #{e.class} #{e.message}"
68
+ end
69
+
70
+ def prestart_end_event
71
+ run_id ? "prestart_end_#{run_id}" : "prestart_end"
72
+ end
73
+
74
+ def restart?
75
+ old_pid != server.pid
76
+ end
77
+
78
+ def first_worker?
79
+ worker.nr == 0
80
+ end
81
+
82
+ def old_pid
83
+ "#{server.config[:pid]}.oldbin"
84
+ end
85
+
86
+ end
87
+ end; end
data/lib/uc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Uc
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
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-05-19 00:00:00.000000000 Z
11
+ date: 2014-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -68,12 +68,16 @@ files:
68
68
  - bin/uc
69
69
  - lib/uc.rb
70
70
  - lib/uc/error.rb
71
+ - lib/uc/lock.rb
71
72
  - lib/uc/logger.rb
73
+ - lib/uc/mq_logger.rb
72
74
  - lib/uc/mqueue.rb
73
75
  - lib/uc/server.rb
74
76
  - lib/uc/shell_helper.rb
75
- - lib/uc/unicorn.rb
76
- - lib/uc/unicorn_config.rb
77
+ - lib/uc/unicorn/api.rb
78
+ - lib/uc/unicorn/config.rb
79
+ - lib/uc/unicorn/prestart.rb
80
+ - lib/uc/unicorn/rolling_restart.rb
77
81
  - lib/uc/version.rb
78
82
  - uc.gemspec
79
83
  homepage: ''
data/lib/uc/unicorn.rb DELETED
@@ -1,70 +0,0 @@
1
- require 'uc/mqueue'
2
- module Uc
3
- module Unicorn
4
-
5
- def self.queue_file
6
- "config/unicorn_mq"
7
- end
8
-
9
- def self.rolling_restart(server, worker, queue_name: nil, sleep_secs: 1)
10
- queue_name ||= get_queue_name
11
- old_pid = "#{server.config[:pid]}.oldbin"
12
- if old_pid != server.pid
13
- sleep sleep_secs
14
- begin
15
- sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
16
- Process.kill(sig, File.read(old_pid).to_i)
17
-
18
- mq = ::Uc::Mqueue.new(queue_name)
19
- writer = mq.nb_writer
20
- writer.send("started worker #{worker.nr + 1}")
21
- if sig == :QUIT
22
- writer.send("fin")
23
- end
24
- rescue Errno::ENOENT, Errno::ESRCH, Errno::EAGAIN => e
25
- end
26
- end
27
- end
28
-
29
- def self.clean_env
30
- ENV.delete "BUNDLE_BIN_PATH"
31
- ENV.delete "RUBYLIB"
32
- ENV.delete "RUBYOPT"
33
- ENV.delete "GEM_HOME"
34
- ENV.delete "GEM_PATH"
35
- end
36
-
37
-
38
- def self.get_queue_name
39
- queue_name = queue_name_from_file
40
- queue_name ||= "unicorn_#{Process.uid}"
41
- return queue_name
42
- end
43
-
44
- def self.queue_name_from_file
45
- queue_file = Pathname.new self.queue_file
46
- queue_name = nil
47
- if queue_file.readable?
48
- queue_name = File.read(queue_file).chomp
49
- queue_name = (queue_name.empty? ? nil : queue_name)
50
- end
51
- return queue_name
52
- end
53
-
54
- def self.pre_start(server, worker, url: "/")
55
- app = server.instance_variable_get("@app")
56
- response = app.call(rack_request(url))
57
- body = response[2]
58
- body.close
59
- rescue => e
60
- puts "WARN: pre start url failed : #{e.message}"
61
- end
62
-
63
- private
64
-
65
- def self.rack_request(url)
66
- Rack::MockRequest.env_for("http://127.0.0.1/#{url}")
67
- end
68
-
69
- end
70
- end