mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-13 03:22:22 -05:00
Improved startup/shutdown of tornado.
Fixed issues with notifications related to tornado.
This commit is contained in:
parent
04681b3297
commit
abff43f568
11
SickBeard.py
11
SickBeard.py
@ -361,12 +361,8 @@ def main():
|
||||
'https_key': sickbeard.HTTPS_KEY,
|
||||
}
|
||||
|
||||
# init tornado web server
|
||||
sickbeard.webserveInitScheduler = sickbeard.scheduler.Scheduler(webserverInit(options),
|
||||
cycleTime=datetime.timedelta(seconds=3),
|
||||
threadName="TORNADO",
|
||||
silent=True,
|
||||
runImmediately=True)
|
||||
# init tornado server
|
||||
sickbeard.WEBSERVER = webserverInit(options)
|
||||
|
||||
# Build from the DB to start with
|
||||
logger.log(u"Loading initial show list")
|
||||
@ -375,6 +371,9 @@ def main():
|
||||
# Fire up all our threads
|
||||
sickbeard.start()
|
||||
|
||||
# start tornado thread
|
||||
sickbeard.WEBSERVER.thread.start()
|
||||
|
||||
# Launch browser if we're supposed to
|
||||
if sickbeard.LAUNCH_BROWSER and not noLaunch and not sickbeard.DAEMON:
|
||||
sickbeard.launchBrowser(startPort)
|
||||
|
@ -29,7 +29,7 @@ from urllib2 import getproxies
|
||||
from threading import Lock
|
||||
|
||||
# apparently py2exe won't build these unless they're imported somewhere
|
||||
from sickbeard import providers, metadata, config
|
||||
from sickbeard import providers, metadata, config, webserveInit
|
||||
from sickbeard.providers.generic import GenericProvider
|
||||
from providers import ezrss, tvtorrents, btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, \
|
||||
omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, nextgen, speedcd, nyaatorrents, fanzub
|
||||
@ -77,6 +77,7 @@ PIDFILE = ''
|
||||
|
||||
DAEMON = None
|
||||
NO_RESIZE = False
|
||||
WEBSERVER = None
|
||||
|
||||
maintenanceScheduler = None
|
||||
dailySearchScheduler = None
|
||||
@ -89,7 +90,6 @@ properFinderScheduler = None
|
||||
autoPostProcesserScheduler = None
|
||||
subtitlesFinderScheduler = None
|
||||
traktWatchListCheckerScheduler = None
|
||||
webserveInitScheduler = None
|
||||
|
||||
showList = None
|
||||
loadingShowList = None
|
||||
@ -479,7 +479,7 @@ def initialize(consoleLogging=True):
|
||||
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, REMOTE_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, \
|
||||
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||
ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
||||
ANIME_SPLIT_HOME, maintenanceScheduler, SCENE_DEFAULT, WEB_DATA_ROOT, webserveInitScheduler
|
||||
ANIME_SPLIT_HOME, maintenanceScheduler, SCENE_DEFAULT, WEB_DATA_ROOT, WEBSERVER
|
||||
|
||||
if __INITIALIZED__:
|
||||
return False
|
||||
@ -1119,15 +1119,12 @@ def start():
|
||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
||||
subtitlesFinderScheduler, USE_SUBTITLES,traktWatchListCheckerScheduler, \
|
||||
dailySearchScheduler, webserveInitScheduler, started
|
||||
dailySearchScheduler, started
|
||||
|
||||
with INIT_LOCK:
|
||||
|
||||
if __INITIALIZED__:
|
||||
|
||||
# start tornado web server
|
||||
webserveInitScheduler.thread.start()
|
||||
|
||||
# start the maintenance scheduler
|
||||
maintenanceScheduler.thread.start()
|
||||
logger.log(u"Performing initial maintenance tasks, please wait ...")
|
||||
@ -1173,7 +1170,7 @@ def halt():
|
||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
||||
subtitlesFinderScheduler, traktWatchListCheckerScheduler, \
|
||||
dailySearchScheduler, webserveInitScheduler, started
|
||||
dailySearchScheduler, started
|
||||
|
||||
with INIT_LOCK:
|
||||
|
||||
@ -1183,13 +1180,6 @@ def halt():
|
||||
|
||||
# abort all the threads
|
||||
|
||||
webserveInitScheduler.about = True
|
||||
logger.log(u"Waiting for the TORNADO thread to exit")
|
||||
try:
|
||||
webserveInitScheduler.thread.join(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
maintenanceScheduler.abort = True
|
||||
logger.log(u"Waiting for the MAINTENANCE scheduler thread to exit")
|
||||
try:
|
||||
@ -1197,13 +1187,6 @@ def halt():
|
||||
except:
|
||||
pass
|
||||
|
||||
dailySearchScheduler.abort = True
|
||||
logger.log(u"Waiting for the DAILYSEARCHER thread to exit")
|
||||
try:
|
||||
dailySearchScheduler.thread.join(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
backlogSearchScheduler.abort = True
|
||||
logger.log(u"Waiting for the BACKLOG thread to exit")
|
||||
try:
|
||||
@ -1310,16 +1293,12 @@ def saveAll():
|
||||
|
||||
|
||||
def saveAndShutdown(restart=False):
|
||||
global WEBSERVER
|
||||
|
||||
halt()
|
||||
saveAll()
|
||||
|
||||
logger.log(u"Killing tornado")
|
||||
try:
|
||||
IOLoop.current().stop()
|
||||
except RuntimeError:
|
||||
pass
|
||||
except:
|
||||
logger.log('Failed shutting down the server: %s' % traceback.format_exc(), logger.ERROR)
|
||||
IOLoop.instance().add_callback(WEBSERVER.shutdown)
|
||||
|
||||
if CREATEPID:
|
||||
logger.log(u"Removing pidfile " + str(PIDFILE))
|
||||
|
@ -163,7 +163,7 @@ def change_AUTOPOSTPROCESSER_FREQUENCY(freq):
|
||||
if sickbeard.AUTOPOSTPROCESSER_FREQUENCY < sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY:
|
||||
sickbeard.AUTOPOSTPROCESSER_FREQUENCY = sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY
|
||||
|
||||
sickbeard.autoPostProcessorScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
|
||||
sickbeard.autoPostProcesserScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
|
||||
|
||||
def change_DAILYSEARCH_FREQUENCY(freq):
|
||||
sickbeard.DAILYSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_DAILYSEARCH_FREQUENCY)
|
||||
|
@ -190,6 +190,7 @@ class IndexHandler(RedirectHandler):
|
||||
args[arg] = value[0]
|
||||
return args
|
||||
|
||||
@asynchronous
|
||||
def _dispatch(self):
|
||||
"""
|
||||
Load up the requested URL if it matches one of our own methods.
|
||||
@ -235,12 +236,10 @@ class IndexHandler(RedirectHandler):
|
||||
def get_current_user(self):
|
||||
return self.get_secure_cookie("user")
|
||||
|
||||
@asynchronous
|
||||
@authenticated
|
||||
def get(self, *args, **kwargs):
|
||||
return self._dispatch()
|
||||
|
||||
@asynchronous
|
||||
def post(self, *args, **kwargs):
|
||||
return self._dispatch()
|
||||
|
||||
@ -1065,7 +1064,7 @@ class Manage(IndexHandler):
|
||||
|
||||
exceptions_list = []
|
||||
|
||||
curErrors += Home().editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
||||
curErrors += self.editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
||||
new_flatten_folders, new_paused, subtitles=new_subtitles, anime=new_anime,
|
||||
scene=new_scene, directCall=True)
|
||||
|
||||
@ -1602,9 +1601,9 @@ class ConfigPostProcessing(IndexHandler):
|
||||
config.change_AUTOPOSTPROCESSER_FREQUENCY(autopostprocesser_frequency)
|
||||
|
||||
if sickbeard.PROCESS_AUTOMATICALLY:
|
||||
sickbeard.autoPostProcessorScheduler.silent = False
|
||||
sickbeard.autoPostProcesserScheduler.silent = False
|
||||
else:
|
||||
sickbeard.autoPostProcessorScheduler.silent = True
|
||||
sickbeard.autoPostProcesserScheduler.silent = True
|
||||
|
||||
if unpack:
|
||||
if self.isRarSupported() != 'not supported':
|
||||
@ -3281,8 +3280,7 @@ class Home(IndexHandler):
|
||||
title = "Shutting down"
|
||||
message = "SickRage is shutting down..."
|
||||
|
||||
return _genericMessage(title, message)
|
||||
|
||||
return self.finish(_genericMessage(title, message))
|
||||
|
||||
def restart(self, pid=None):
|
||||
|
||||
@ -3311,8 +3309,8 @@ class Home(IndexHandler):
|
||||
t = PageTemplate(file="restart_bare.tmpl")
|
||||
return self.finish(_munge(t))
|
||||
else:
|
||||
return _genericMessage("Update Failed",
|
||||
"Update wasn't successful, not restarting. Check your log for more information.")
|
||||
return self.finish(_genericMessage("Update Failed",
|
||||
"Update wasn't successful, not restarting. Check your log for more information."))
|
||||
|
||||
|
||||
def displayShow(self, show=None):
|
||||
@ -3477,7 +3475,7 @@ class Home(IndexHandler):
|
||||
if directCall:
|
||||
return [errString]
|
||||
else:
|
||||
return _genericMessage("Error", errString)
|
||||
return self.finish(_genericMessage("Error", errString))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
@ -3486,7 +3484,7 @@ class Home(IndexHandler):
|
||||
if directCall:
|
||||
return [errString]
|
||||
else:
|
||||
return _genericMessage("Error", errString)
|
||||
return self.finish(_genericMessage("Error", errString))
|
||||
|
||||
showObj.exceptions = scene_exceptions.get_scene_exceptions(showObj.indexerid)
|
||||
|
||||
@ -3727,16 +3725,16 @@ class Home(IndexHandler):
|
||||
def deleteShow(self, show=None):
|
||||
|
||||
if show is None:
|
||||
return _genericMessage("Error", "Invalid show ID")
|
||||
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if showObj is None:
|
||||
return _genericMessage("Error", "Unable to find the specified show")
|
||||
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||
|
||||
if sickbeard.showQueueScheduler.action.isBeingAdded(
|
||||
showObj) or sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
|
||||
return _genericMessage("Error", "Shows can't be deleted while they're being added or updated.")
|
||||
return self.finish(_genericMessage("Error", "Shows can't be deleted while they're being added or updated."))
|
||||
|
||||
showObj.deleteShow()
|
||||
|
||||
@ -3747,12 +3745,12 @@ class Home(IndexHandler):
|
||||
def refreshShow(self, show=None):
|
||||
|
||||
if show is None:
|
||||
return _genericMessage("Error", "Invalid show ID")
|
||||
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if showObj is None:
|
||||
return _genericMessage("Error", "Unable to find the specified show")
|
||||
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||
|
||||
# force the update from the DB
|
||||
try:
|
||||
@ -3769,12 +3767,12 @@ class Home(IndexHandler):
|
||||
def updateShow(self, show=None, force=0):
|
||||
|
||||
if show is None:
|
||||
return _genericMessage("Error", "Invalid show ID")
|
||||
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if showObj is None:
|
||||
return _genericMessage("Error", "Unable to find the specified show")
|
||||
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||
|
||||
# force the update
|
||||
try:
|
||||
@ -3792,12 +3790,12 @@ class Home(IndexHandler):
|
||||
def subtitleShow(self, show=None, force=0):
|
||||
|
||||
if show is None:
|
||||
return _genericMessage("Error", "Invalid show ID")
|
||||
return self.finish(_genericMessage("Error", "Invalid show ID"))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if showObj is None:
|
||||
return _genericMessage("Error", "Unable to find the specified show")
|
||||
return self.finish(_genericMessage("Error", "Unable to find the specified show"))
|
||||
|
||||
# search and download subtitles
|
||||
sickbeard.showQueueScheduler.action.downloadSubtitles(showObj, bool(force)) # @UndefinedVariable
|
||||
@ -3840,7 +3838,7 @@ class Home(IndexHandler):
|
||||
ui.notifications.error('Error', errMsg)
|
||||
return json.dumps({'result': 'error'})
|
||||
else:
|
||||
return _genericMessage("Error", errMsg)
|
||||
return self.finish(_genericMessage("Error", errMsg))
|
||||
|
||||
if not statusStrings.has_key(int(status)):
|
||||
errMsg = "Invalid status"
|
||||
@ -3848,7 +3846,7 @@ class Home(IndexHandler):
|
||||
ui.notifications.error('Error', errMsg)
|
||||
return json.dumps({'result': 'error'})
|
||||
else:
|
||||
return _genericMessage("Error", errMsg)
|
||||
return self.finish(_genericMessage("Error", errMsg))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
@ -3858,7 +3856,7 @@ class Home(IndexHandler):
|
||||
ui.notifications.error('Error', errMsg)
|
||||
return json.dumps({'result': 'error'})
|
||||
else:
|
||||
return _genericMessage("Error", errMsg)
|
||||
return self.finish(_genericMessage("Error", errMsg))
|
||||
|
||||
segment = {}
|
||||
if eps is not None:
|
||||
@ -3873,7 +3871,7 @@ class Home(IndexHandler):
|
||||
epObj = showObj.getEpisode(int(epInfo[0]), int(epInfo[1]))
|
||||
|
||||
if epObj is None:
|
||||
return _genericMessage("Error", "Episode couldn't be retrieved")
|
||||
return self.finish(_genericMessage("Error", "Episode couldn't be retrieved"))
|
||||
|
||||
if int(status) in [WANTED, FAILED]:
|
||||
# figure out what episodes are wanted so we can backlog them
|
||||
@ -3949,17 +3947,17 @@ class Home(IndexHandler):
|
||||
def testRename(self, show=None):
|
||||
|
||||
if show is None:
|
||||
return _genericMessage("Error", "You must specify a show")
|
||||
return self.finish(_genericMessage("Error", "You must specify a show"))
|
||||
|
||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if showObj is None:
|
||||
return _genericMessage("Error", "Show not in show list")
|
||||
return self.finish(_genericMessage("Error", "Show not in show list"))
|
||||
|
||||
try:
|
||||
show_loc = showObj.location # @UnusedVariable
|
||||
except exceptions.ShowDirNotFoundException:
|
||||
return _genericMessage("Error", "Can't rename episodes when the show dir is missing.")
|
||||
return self.finish(_genericMessage("Error", "Can't rename episodes when the show dir is missing."))
|
||||
|
||||
ep_obj_rename_list = []
|
||||
|
||||
@ -3996,18 +3994,18 @@ class Home(IndexHandler):
|
||||
|
||||
if show is None or eps is None:
|
||||
errMsg = "You must specify a show and at least one episode"
|
||||
return _genericMessage("Error", errMsg)
|
||||
return self.finish(_genericMessage("Error", errMsg))
|
||||
|
||||
show_obj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
|
||||
|
||||
if show_obj is None:
|
||||
errMsg = "Error", "Show not in show list"
|
||||
return _genericMessage("Error", errMsg)
|
||||
return self.finish(_genericMessage("Error", errMsg))
|
||||
|
||||
try:
|
||||
show_loc = show_obj.location # @UnusedVariable
|
||||
except exceptions.ShowDirNotFoundException:
|
||||
return _genericMessage("Error", "Can't rename episodes when the show dir is missing.")
|
||||
return self.finish(_genericMessage("Error", "Can't rename episodes when the show dir is missing."))
|
||||
|
||||
if eps is None:
|
||||
self.redirect("/home/displayShow?show=" + show)
|
||||
|
@ -1,11 +1,17 @@
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import datetime
|
||||
import sickbeard
|
||||
import webserve
|
||||
import tornado.httpserver
|
||||
import tornado.ioloop
|
||||
from sickbeard.exceptions import ex
|
||||
from sickbeard import logger
|
||||
from sickbeard.helpers import create_https_certificates
|
||||
from tornado.web import Application, StaticFileHandler, HTTPError, RedirectHandler
|
||||
from tornado.web import Application, StaticFileHandler, RedirectHandler, HTTPError
|
||||
from tornado.httpserver import HTTPServer
|
||||
from tornado.ioloop import IOLoop
|
||||
|
||||
|
||||
class MultiStaticFileHandler(StaticFileHandler):
|
||||
def initialize(self, paths, default_filename=None):
|
||||
@ -27,17 +33,27 @@ class MultiStaticFileHandler(StaticFileHandler):
|
||||
# Oops file not found anywhere!
|
||||
raise HTTPError(404)
|
||||
|
||||
|
||||
class webserverInit():
|
||||
def __init__(self, options):
|
||||
def __init__(self, options, cycleTime=datetime.timedelta(seconds=3)):
|
||||
|
||||
self.amActive = False
|
||||
options.setdefault('port', 8081)
|
||||
options.setdefault('host', '0.0.0.0')
|
||||
options.setdefault('log_dir', None)
|
||||
options.setdefault('username', '')
|
||||
options.setdefault('password', '')
|
||||
options.setdefault('web_root', '/')
|
||||
assert isinstance(options['port'], int)
|
||||
assert 'data_root' in options
|
||||
self.lastRun = datetime.datetime.fromordinal(1)
|
||||
self.cycleTime = cycleTime
|
||||
self.abort = False
|
||||
|
||||
self.server = None
|
||||
self.thread = None
|
||||
|
||||
self.options = options
|
||||
self.options.setdefault('port', 8081)
|
||||
self.options.setdefault('host', '0.0.0.0')
|
||||
self.options.setdefault('log_dir', None)
|
||||
self.options.setdefault('username', '')
|
||||
self.options.setdefault('password', '')
|
||||
self.options.setdefault('web_root', '/')
|
||||
assert isinstance(self.options['port'], int)
|
||||
assert 'data_root' in self.options
|
||||
|
||||
def http_error_401_hander(status, message, traceback, version):
|
||||
""" Custom handler for 401 error """
|
||||
@ -72,12 +88,12 @@ class webserverInit():
|
||||
<br/>
|
||||
</body>
|
||||
</html>
|
||||
''' % options['web_root']
|
||||
''' % self.options['web_root']
|
||||
|
||||
# tornado setup
|
||||
enable_https = options['enable_https']
|
||||
https_cert = options['https_cert']
|
||||
https_key = options['https_key']
|
||||
enable_https = self.options['enable_https']
|
||||
https_cert = self.options['https_cert']
|
||||
https_key = self.options['https_key']
|
||||
|
||||
if enable_https:
|
||||
# If either the HTTPS certificate or key do not exist, make some self-signed ones.
|
||||
@ -103,42 +119,84 @@ class webserverInit():
|
||||
|
||||
# Index Handler
|
||||
app.add_handlers(".*$", [
|
||||
(r"/", tornado.web.RedirectHandler, {'url': '/home/'}),
|
||||
(r"/", RedirectHandler, {'url': '/home/'}),
|
||||
(r'/login', webserve.LoginHandler),
|
||||
(r'%s(.*)(/?)' % options['web_root'], webserve.IndexHandler)
|
||||
(r'%s(.*)(/?)' % self.options['web_root'], webserve.IndexHandler)
|
||||
])
|
||||
|
||||
# Static Path Handler
|
||||
app.add_handlers(".*$", [
|
||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'images'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'images'),
|
||||
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'images'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(self.options['data_root'], 'images'),
|
||||
os.path.join(sickbeard.CACHE_DIR, 'images'),
|
||||
os.path.join(sickbeard.CACHE_DIR, 'images', 'thumbnails')]}),
|
||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'css'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'css')]}),
|
||||
('%s/%s/(.*)([^/]*)' % (options['web_root'], 'js'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(options['data_root'], 'js')]})
|
||||
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'css'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(self.options['data_root'], 'css')]}),
|
||||
('%s/%s/(.*)([^/]*)' % (self.options['web_root'], 'js'), MultiStaticFileHandler,
|
||||
{'paths': [os.path.join(self.options['data_root'], 'js')]})
|
||||
|
||||
])
|
||||
|
||||
if enable_https:
|
||||
protocol = "https"
|
||||
server = tornado.httpserver.HTTPServer(app, no_keep_alive=True,
|
||||
ssl_options={"certfile": https_cert, "keyfile": https_key})
|
||||
self.server = HTTPServer(app, no_keep_alive=True,
|
||||
ssl_options={"certfile": https_cert, "keyfile": https_key})
|
||||
else:
|
||||
protocol = "http"
|
||||
server = tornado.httpserver.HTTPServer(app, no_keep_alive=True)
|
||||
self.server = HTTPServer(app, no_keep_alive=True)
|
||||
|
||||
logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
|
||||
options['port']) + "/")
|
||||
logger.log(u"Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
|
||||
self.options['port']) + "/")
|
||||
|
||||
server.listen(options['port'], options['host'])
|
||||
self.server.listen(self.options['port'], self.options['host'])
|
||||
|
||||
if self.thread == None or not self.thread.isAlive():
|
||||
self.thread = threading.Thread(None, self.monitor, 'TORNADO')
|
||||
|
||||
def monitor(self):
|
||||
|
||||
while True:
|
||||
|
||||
currentTime = datetime.datetime.now()
|
||||
|
||||
if currentTime - self.lastRun > self.cycleTime:
|
||||
self.lastRun = currentTime
|
||||
try:
|
||||
logger.log(u"Starting tornado", logger.DEBUG)
|
||||
|
||||
IOLoop.instance().start()
|
||||
except Exception, e:
|
||||
logger.log(u"Exception generated in tornado: " + ex(e), logger.ERROR)
|
||||
logger.log(repr(traceback.format_exc()), logger.DEBUG)
|
||||
|
||||
if self.abort:
|
||||
self.abort = False
|
||||
self.thread = None
|
||||
return
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
def shutdown(self):
|
||||
|
||||
logger.logging.info('Shutting down tornado')
|
||||
|
||||
def run(self, force=False):
|
||||
try:
|
||||
self.amActive = True
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
self.abort = True
|
||||
self.server.stop()
|
||||
|
||||
deadline = time.time() + 10
|
||||
|
||||
io_loop = IOLoop.instance()
|
||||
def stop_loop():
|
||||
now = time.time()
|
||||
|
||||
if now < deadline:
|
||||
if io_loop._callbacks:
|
||||
io_loop.add_timeout(now + 1, stop_loop)
|
||||
return
|
||||
stop_loop()
|
||||
self.thread.join(10)
|
||||
except:
|
||||
self.amActive = False
|
||||
raise
|
||||
pass
|
||||
|
||||
logger.logging.info('Tornado is now shutdown')
|
Loading…
Reference in New Issue
Block a user