Skip to content

Commit

Permalink
Refactored WSGIServer handling
Browse files Browse the repository at this point in the history
Restart of gevent server now working
  • Loading branch information
OzzieIsaacs committed Jul 9, 2018
1 parent a298470 commit 404b29b
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 91 deletions.
46 changes: 7 additions & 39 deletions cps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,12 @@
sys.path.append(os.path.join(base_path, 'cps'))
sys.path.append(os.path.join(base_path, 'vendor'))

from cps import web
try:
from gevent.pywsgi import WSGIServer
gevent_present = True
except ImportError:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
gevent_present = False
from cps.server import Server

if __name__ == '__main__':
if gevent_present:
web.app.logger.info('Attempting to start gevent')
web.start_gevent()
else:
web.app.logger.info('Starting Tornado webserver')
# Max Buffersize set to 200MB
if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile():
ssl={"certfile": web.ub.config.get_config_certfile(),
"keyfile": web.ub.config.get_config_keyfile()}
else:
ssl=None
http_server = HTTPServer(WSGIContainer(web.app),
max_buffer_size = 209700000,
ssl_options=ssl)
http_server.listen(web.ub.config.config_port)
IOLoop.instance().start()
IOLoop.instance().close(True)

if web.helper.global_task == 0:
web.app.logger.info("Performing restart of Calibre-web")
if os.name == 'nt':
arguments = ["\"" + sys.executable + "\""]
for e in sys.argv:
arguments.append("\"" + e + "\"")
os.execv(sys.executable, arguments)
else:
os.execl(sys.executable, sys.executable, *sys.argv)
else:
web.app.logger.info("Performing shutdown of Calibre-web")
sys.exit(0)
Server.startServer()





14 changes: 3 additions & 11 deletions cps/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
import shutil
import requests
import zipfile
from tornado.ioloop import IOLoop
try:
import gdriveutils as gd
except ImportError:
pass
import web
import server

try:
import unidecode
Expand All @@ -50,7 +50,6 @@
use_unidecode = False

# Global variables
global_task = None
updater_thread = None

RET_SUCCESS = 1
Expand Down Expand Up @@ -388,7 +387,6 @@ def __init__(self):
self.status = 0

def run(self):
global global_task
self.status = 1
r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True)
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
Expand All @@ -400,19 +398,13 @@ def run(self):
self.status = 4
self.update_source(os.path.join(tmp_dir, os.path.splitext(fname)[0]), ub.config.get_main_dir)
self.status = 5
global_task = 0
db.session.close()
db.engine.dispose()
ub.session.close()
ub.engine.dispose()
self.status = 6

if web.gevent_server:
web.gevent_server.stop()
else:
# stop tornado server
server = IOLoop.instance()
server.add_callback(server.stop)
server.Server.setRestartTyp(True)
server.Server.stopServer()
self.status = 7

def get_update_status(self):
Expand Down
103 changes: 103 additions & 0 deletions cps/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-


from socket import error as SocketError
import sys
import os
try:
from gevent.pywsgi import WSGIServer
from gevent import monkey
from gevent.pool import Pool
from gevent import __version__ as geventVersion
gevent_present = True
except ImportError:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado import version as tornadoVersion
gevent_present = False

import web


class server:

wsgiserver = None
restart= False

def __init__(self):
pass

def start_gevent(self):
try:
ssl_args = dict()
if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile():
ssl_args = {"certfile": web.ub.config.get_config_certfile(),
"keyfile": web.ub.config.get_config_keyfile()}
if os.name == 'nt':
self.wsgiserver= WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args)
else:
self.wsgiserver = WSGIServer(('', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args)
self.wsgiserver.serve_forever()

except SocketError:
web.app.logger.info('Unable to listen on \'\', trying on IPv4 only...')
self.wsgiserver = WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args)
self.wsgiserver.serve_forever()
except:
pass

def startServer(self):
if gevent_present:
web.app.logger.info('Starting Gevent server')
# leave subprocess out to allow forking for fetchers and processors
monkey.patch_all(subprocess=False)
self.start_gevent()
else:
web.app.logger.info('Starting Tornado server')
if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile():
ssl={"certfile": web.ub.config.get_config_certfile(),
"keyfile": web.ub.config.get_config_keyfile()}
else:
ssl=None
# Max Buffersize set to 200MB
http_server = HTTPServer(WSGIContainer(web.app),
max_buffer_size = 209700000,
ssl_options=ssl)
http_server.listen(web.ub.config.config_port)
self.wsgiserver=IOLoop.instance()
self.wsgiserver.start() # wait for stop signal
self.wsgiserver.close(True)

if self.restart == True:
web.app.logger.info("Performing restart of Calibre-web")
if os.name == 'nt':
arguments = ["\"" + sys.executable + "\""]
for e in sys.argv:
arguments.append("\"" + e + "\"")
os.execv(sys.executable, arguments)
else:
os.execl(sys.executable, sys.executable, *sys.argv)
else:
web.app.logger.info("Performing shutdown of Calibre-web")
sys.exit(0)

def setRestartTyp(self,starttyp):
self.restart=starttyp

def stopServer(self):
if gevent_present:
self.wsgiserver.close()
else:
self.wsgiserver.add_callback(self.wsgiserver.stop)

def getNameVersion(self):
if gevent_present:
return {'gevent':geventVersion}
else:
return {'tornado':tornadoVersion}


# Start Instance of Server
Server=server()
16 changes: 12 additions & 4 deletions cps/templates/stats.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ <h3>{{_('Linked libraries')}}</h3>
<th>Python</th>
<td>{{versions['PythonVersion']}}</td>
</tr>
{% if 'tornado' in versions %}
<tr>
<th>Tornado web server</th>
<td>v{{versions['tornado']}}</td>
</tr>
{% endif %}
{% if 'gevent' in versions %}
<tr>
<th>Gevent web server</th>
<td>v{{versions['gevent']}}</td>
</tr>
{% endif %}
<tr>
<th>Kindlegen</th>
<td>{{versions['KindlegenVersion']}}</td>
Expand Down Expand Up @@ -70,10 +82,6 @@ <h3>{{_('Linked libraries')}}</h3>
<th>Flask Principal</th>
<td>v{{versions['flask_principal']}}</td>
</tr>
<tr>
<th>Tornado web server</th>
<td>v{{versions['tornado']}}</td>
</tr>
<tr>
<th>ISO639 Languages</th>
<td>v{{versions['iso639']}}</td>
Expand Down
47 changes: 10 additions & 37 deletions cps/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,12 @@
import re
import db
from shutil import move, copyfile
from tornado.ioloop import IOLoop
import shutil
import gdriveutils
import tempfile
import hashlib
from redirect import redirect_back, is_safe_url

from tornado import version as tornadoVersion
from socket import error as SocketError

try:
from urllib.parse import quote
Expand All @@ -93,13 +90,13 @@
from flask_login.__about__ import __version__ as flask_loginVersion

import time
import server

current_milli_time = lambda: int(round(time.time() * 1000))


# Global variables
gdrive_watch_callback_token = 'target=calibreweb-watch_files'
global_task = None

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx', 'fb2'])

Expand Down Expand Up @@ -218,8 +215,6 @@ def __call__(self, environ, start_response):
app.wsgi_app = ReverseProxied(app.wsgi_app)
cache_buster.init_cache_busting(app)

gevent_server = None

formatter = logging.Formatter(
"[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s")
file_handler = RotatingFileHandler(config.get_config_logfile(), maxBytes=50000, backupCount=2)
Expand Down Expand Up @@ -1471,7 +1466,8 @@ def stats():
versions['flask'] = flaskVersion
versions['flasklogin'] = flask_loginVersion
versions['flask_principal'] = flask_principalVersion
versions['tornado'] = tornadoVersion
versions.update(server.Server.getNameVersion())
# versions['tornado'] = tornadoVersion
versions['iso639'] = iso639Version
versions['requests'] = requests.__version__
versions['pysqlite'] = db.engine.dialect.dbapi.version
Expand Down Expand Up @@ -1640,25 +1636,23 @@ def updateMetaData():
@login_required
@admin_required
def shutdown():
# global global_task
task = int(request.args.get("parameter").strip())
helper.global_task = task
if task == 1 or task == 0: # valid commandos received
# close all database connections
db.session.close()
db.engine.dispose()
ub.session.close()
ub.engine.dispose()
# stop gevent server
# gevent_server.stop()
# stop tornado server
server = IOLoop.instance()
server.add_callback(server.stop)

showtext = {}
if task == 0:
showtext['text'] = _(u'Server restarted, please reload page')
server.Server.setRestartTyp(True)
else:
showtext['text'] = _(u'Performing shutdown of server, please close window')
server.Server.setRestartTyp(False)
server.Server.stopServer()
return json.dumps(showtext)
else:
if task == 2:
Expand Down Expand Up @@ -2498,7 +2492,6 @@ def basic_configuration():


def configuration_helper(origin):
# global global_task
reboot_required = False
gdriveError=None
db_change = False
Expand Down Expand Up @@ -2705,10 +2698,9 @@ def configuration_helper(origin):
# db.engine.dispose() # ToDo verify correct
ub.session.close()
ub.engine.dispose()
# stop tornado server
server = IOLoop.instance()
server.add_callback(server.stop)
helper.global_task = 0
# stop Server
server.Server.setRestartTyp(True)
server.Server.stopServer()
app.logger.info('Reboot required, restarting')
if origin:
success = True
Expand Down Expand Up @@ -3386,22 +3378,3 @@ def upload():
else:
return redirect(url_for("index"))

def start_gevent():
from gevent.pywsgi import WSGIServer
global gevent_server
try:
ssl_args=dict()
if ub.config.get_config_certfile() and ub.config.get_config_keyfile():
ssl_args = {"certfile": ub.config.get_config_certfile(),
"keyfile": ub.config.get_config_keyfile()}
if os.name == 'nt':
gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app, **ssl_args)
else:
gevent_server = WSGIServer(('', ub.config.config_port), app, **ssl_args)
gevent_server.serve_forever()
except SocketError:
app.logger.info('Unable to listen on \'\', trying on IPv4 only...')
gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app, **ssl_args)
gevent_server.serve_forever()
except:
pass

0 comments on commit 404b29b

Please sign in to comment.