Skip to content
Browse files

HH-23763 remade logic for start/stop

  • Loading branch information...
1 parent e5bdfbf commit b3c477d147a76d033b1f931c3ddd1d64ebb0c67b @katraev katraev committed
Showing with 48 additions and 14 deletions.
  1. +14 −3 tornado_util/server.py
  2. +34 −11 tornado_util/supervisor.py
View
17 tornado_util/server.py
@@ -26,6 +26,7 @@
'''
import time
+import lockfile
from functools import partial
import logging
@@ -55,10 +56,8 @@ def bootstrap(config_file, default_port=8080):
tornado.options.define('port', default_port, int)
tornado.options.define('daemonize', True, bool)
tornado.options.define('autoreload', True, bool)
-
-
-
tornado.options.parse_command_line()
+
if options.config:
config_to_read = options.config
else:
@@ -90,6 +89,8 @@ def main(app, on_stop_request = lambda: None, on_ioloop_stop = lambda: None):
import tornado.web
try:
+ lock = lockfile.FileLock(options.pidfile)
+ lock.acquire()
log.info('starting server on %s:%s', options.host, options.port)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port, options.host)
@@ -107,21 +108,31 @@ def stop_handler(signum, frame):
if tornado.ioloop.IOLoop.instance().running():
log.info('Going down in %s s.', options.stop_timeout)
+
def timeo_stop():
if tornado.ioloop.IOLoop.instance().running():
log.info('Stoping ioloop.')
tornado.ioloop.IOLoop.instance().stop()
log.info('Stoped.')
+ lock.release()
@curlup
curlup added a note

а если ioloop ктото в другом месте стопанул? нужно наверное вешаться на stop у ioloop`а и тогда освобождать.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
on_ioloop_stop()
def add_timeo():
tornado.ioloop.IOLoop.instance().add_timeout(time.time()+options.stop_timeout, timeo_stop)
tornado.ioloop.IOLoop.instance().add_callback(add_timeo)
+
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
on_stop_request()
import signal
signal.signal(signal.SIGTERM, stop_handler)
io_loop.start()
+ except lockfile.AlreadyLocked, e:
+ log.exception('pid is locked by another process already')
@curlup
curlup added a note

pidFile ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ raise
+ except lockfile.LockFailed, e:
+ log.exception('failed to create lock')
+ raise
except Exception, e:
log.exception('main failed')
View
45 tornado_util/supervisor.py
@@ -28,6 +28,7 @@
import sys
import urllib2
+import lockfile
import httplib
import logging
import subprocess
@@ -50,6 +51,19 @@
import os.path
import os
+
+def is_alive(port):
+ try:
+ path = options.pidfile_template % dict(port=port)
+ pid = int(file(path).read())
+ if (lockfile.FileLock(options.pidfile_template % dict(port=port)).is_locked()
+ and os.path.exists("/proc/{0}".format(pid)) ):
+ return True
+ return False
+ except Exception:
+ return False
+
+
def is_running(port):
try:
urllib2.urlopen('http://localhost:%s/status/' % (port,))
@@ -60,17 +74,20 @@ def is_running(port):
return False
def start_worker(script, config, port):
+ if is_alive(port):
+ logging.warn("another process already started on %s", port)
+ exit()
+ rm_pidfile(port)
@curlup
curlup added a note

не лишнее ли?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
logging.debug('start worker %s', port)
args = [script,
'--config=%s' % (config,),
- '--port=%s' % (port,)]
+ '--port=%s' % (port,),
+ '--pidfile=%s' % (options.pidfile_template % dict(port=port),)]
if options.logfile_template:
args.append('--logfile=%s' % (options.logfile_template % dict(port=port),))
- args.append('--pidfile=%s' % (options.pidfile_template % dict(port=port),))
-
return subprocess.Popen(args)
def stop_worker(port):
@@ -89,12 +106,14 @@ def stop_worker(port):
pass
def rm_pidfile(port):
- path = options.pidfile_template % dict(port=port)
- if os.path.exists(path):
- try:
- os.remove(path)
- except :
- logging.warning('failed to rm pidfile %s', path)
+ pid_path = options.pidfile_template % dict(port=port)
+ pid_path_lock = options.pidfile_template % dict(port=port) + ".lock"''
+ for file_path in (pid_path, pid_path_lock):
+ if os.path.exists(file_path):
+ try:
+ os.remove(file_path)
+ except :
+ logging.warning('failed to rm %s', file_path)
def map_workers(f):
return map(f, [options.port + p for p in range(options.workers_count)])
@@ -106,7 +125,7 @@ def stop():
for i in xrange(3):
map_workers(stop_worker)
time.sleep(options.stop_timeout/3.)
- if not any(map_workers(is_running)):
+ if not any(map_workers(is_alive)):
map_workers(rm_pidfile)
break
else:
@@ -146,7 +165,11 @@ def supervisor(script, config):
logging.getLogger().setLevel(logging.DEBUG)
tornado.options.enable_pretty_logging()
- if cmd == 'start' or cmd == 'restart':
+ if cmd == 'start':
+ start(script, config)
+ sys.exit(status(expect='started'))
+
+ if cmd == 'restart':
stop()
start(script, config)
sys.exit(status(expect='started'))

0 comments on commit b3c477d

Please sign in to comment.
Something went wrong with that request. Please try again.