From bb074d7b63884bccfef050040b2ca6c113c1a683 Mon Sep 17 00:00:00 2001
From: Christopher Allan Webber <cwebber@dustycloud.org>
Date: Wed, 17 Feb 2016 17:39:32 -0800
Subject: [PATCH] Switch from Paste for serving to Waitress
Incredibly, it looks like none of our documentation has to change taking
this route...!
---
lazystarter.sh | 44 +++++----------------------------------
mediagoblin/app.py | 31 ---------------------------
mediagoblin/gmg_commands/serve.py | 1 -
mediagoblin/tests/test_paste.ini | 2 +-
paste.ini | 19 +++++++++--------
setup.py | 6 +-----
6 files changed, 17 insertions(+), 86 deletions(-)
diff --git a/lazystarter.sh b/lazystarter.sh
index 9836279..0ed22fd 100755
|
a
|
b
|
|
| 19 | 19 | selfname=$(basename "$0") |
| 20 | 20 | local_bin="./bin" |
| 21 | 21 | |
| 22 | | # Test whether or not gunicorn is installed |
| 23 | | # ----------------------------------------- |
| 24 | | if [ -f "${local_bin}/python" ]; then |
| 25 | | our_python="${local_bin}/python"; |
| 26 | | else |
| 27 | | our_python="python"; |
| 28 | | fi |
| 29 | | |
| 30 | | if $our_python -c "import sys |
| 31 | | try: |
| 32 | | import gunicorn |
| 33 | | sys.exit(0) |
| 34 | | except ImportError: |
| 35 | | sys.exit(1) |
| 36 | | "; then |
| 37 | | use_gunicorn=true; |
| 38 | | else |
| 39 | | use_gunicorn=false; |
| 40 | | fi |
| 41 | | # ----------------------------------------- |
| 42 | | |
| 43 | 22 | case "$selfname" in |
| 44 | 23 | lazyserver.sh) |
| 45 | | if $use_gunicorn; then |
| 46 | | starter_cmd=gunicorn; |
| 47 | | else |
| 48 | | starter_cmd=paster; |
| 49 | | fi |
| | 24 | starter_cmd=paster; |
| 50 | 25 | ini_prefix=paste |
| 51 | 26 | ;; |
| 52 | 27 | lazycelery.sh) |
| … |
… |
esac
|
| 62 | 37 | if [ "$1" = "-h" ]; then |
| 63 | 38 | echo "$0 [-h] [-c filename.ini] [ARGS_to_${starter_cmd} ...]" |
| 64 | 39 | echo "" |
| 65 | | if $use_gunicorn; then |
| 66 | | echo " For Gunicorn settings, see at:" |
| 67 | | echo " http://docs.gunicorn.org/en/19.0/settings.html" |
| 68 | | else |
| 69 | | echo " For example:" |
| 70 | | echo " $0 -c fcgi.ini port_number=23371" |
| 71 | | echo " or: $0 --server-name=fcgi --log-file=paste.log" |
| 72 | | fi |
| | 40 | echo " For example:" |
| | 41 | echo " $0 -c fcgi.ini port_number=23371" |
| | 42 | echo " or: $0 --server-name=fcgi --log-file=paste.log" |
| 73 | 43 | echo "" |
| 74 | 44 | echo " The configfile defaults to ${ini_prefix}_local.ini," |
| 75 | 45 | echo " if that is readable, otherwise ${ini_prefix}.ini." |
| … |
… |
set -x
|
| 112 | 82 | export CELERY_ALWAYS_EAGER=true |
| 113 | 83 | case "$selfname" in |
| 114 | 84 | lazyserver.sh) |
| 115 | | if $use_gunicorn; then |
| 116 | | $starter --paste "$ini_file" --log-file=- $@; |
| 117 | | else |
| 118 | | $starter serve "$ini_file" "$@" --reload; |
| 119 | | fi |
| | 85 | $starter serve "$ini_file" "$@" --reload; |
| 120 | 86 | ;; |
| 121 | 87 | lazycelery.sh) |
| 122 | 88 | MEDIAGOBLIN_CONFIG="${ini_file}" \ |
diff --git a/mediagoblin/app.py b/mediagoblin/app.py
index b984696..345aa04 100644
|
a
|
b
|
def paste_app_factory(global_config, **app_config):
|
| 365 | 365 | mgoblin_app = hook_transform('wrap_wsgi', mgoblin_app) |
| 366 | 366 | |
| 367 | 367 | return mgoblin_app |
| 368 | | |
| 369 | | |
| 370 | | def paste_server_selector(wsgi_app, global_config=None, **app_config): |
| 371 | | """ |
| 372 | | Select between gunicorn and paste depending on what ia available |
| 373 | | """ |
| 374 | | # See if we can import the gunicorn server... |
| 375 | | # otherwise we'll use the paste server |
| 376 | | try: |
| 377 | | import gunicorn |
| 378 | | except ImportError: |
| 379 | | gunicorn = None |
| 380 | | |
| 381 | | if gunicorn is None: |
| 382 | | # use paste |
| 383 | | from paste.httpserver import server_runner |
| 384 | | |
| 385 | | cleaned_app_config = dict( |
| 386 | | [(key, app_config[key]) |
| 387 | | for key in app_config |
| 388 | | if key in ["host", "port", "handler", "ssl_pem", "ssl_context", |
| 389 | | "server_version", "protocol_version", "start_loop", |
| 390 | | "daemon_threads", "socket_timeout", "use_threadpool", |
| 391 | | "threadpool_workers", "threadpool_options", |
| 392 | | "request_queue_size"]]) |
| 393 | | |
| 394 | | return server_runner(wsgi_app, global_config, **cleaned_app_config) |
| 395 | | else: |
| 396 | | # use gunicorn |
| 397 | | from gunicorn.app.pasterapp import PasterServerApplication |
| 398 | | return PasterServerApplication(wsgi_app, global_config, **app_config) |
diff --git a/mediagoblin/gmg_commands/serve.py b/mediagoblin/gmg_commands/serve.py
index 64400fd..6ded1cf 100644
|
a
|
b
|
class ServeCommand(object):
|
| 29 | 29 | return loadapp(app_spec, name=name, relative_to=relative_to, **kwargs) |
| 30 | 30 | |
| 31 | 31 | def daemonize(self): |
| 32 | | # TODO: pass to gunicorn if available |
| 33 | 32 | pass |
| 34 | 33 | |
| 35 | 34 | def restart_with_reloader(self): |
diff --git a/mediagoblin/tests/test_paste.ini b/mediagoblin/tests/test_paste.ini
index 8d75c3c..1c5f09f 100644
|
a
|
b
|
config = %(here)s/mediagoblin.ini
|
| 13 | 13 | CELERY_ALWAYS_EAGER = true |
| 14 | 14 | |
| 15 | 15 | [server:main] |
| 16 | | use = egg:gunicorn |
| | 16 | use = egg:waitress#main |
| 17 | 17 | host = 127.0.0.1 |
| 18 | 18 | port = 6543 |
diff --git a/paste.ini b/paste.ini
index 68fd9de..ce3f01e 100644
|
a
|
b
|
|
| 6 | 6 | debug = false |
| 7 | 7 | |
| 8 | 8 | [pipeline:main] |
| 9 | | pipeline = errors mediagoblin |
| | 9 | # pipeline = errors mediagoblin |
| | 10 | pipeline = mediagoblin |
| 10 | 11 | |
| 11 | 12 | [app:mediagoblin] |
| 12 | 13 | use = egg:mediagoblin#app |
| … |
… |
debug = false
|
| 51 | 52 | # The server that is run by default. |
| 52 | 53 | # By default, should only be accessable locally |
| 53 | 54 | [server:main] |
| 54 | | use = egg:mediagoblin#paste_server_selector |
| | 55 | use = egg:waitress#main |
| 55 | 56 | host = 127.0.0.1 |
| 56 | 57 | port = 6543 |
| 57 | | # Gunicorn settings. See http://docs.gunicorn.org/en/19.0/settings.html |
| 58 | | # for more information about configuring Gunicorn |
| 59 | | proc_name = gmg |
| 60 | | reload = true |
| 61 | | accesslog = - |
| | 58 | # # Gunicorn settings. See http://docs.gunicorn.org/en/19.0/settings.html |
| | 59 | # # for more information about configuring Gunicorn |
| | 60 | # proc_name = gmg |
| | 61 | # reload = true |
| | 62 | # accesslog = - |
| 62 | 63 | |
| 63 | 64 | ####################### |
| 64 | 65 | # Helper server configs |
| … |
… |
accesslog = -
|
| 69 | 70 | # Use this if you want to run on port 6543 and have MediaGoblin be |
| 70 | 71 | # viewable externally |
| 71 | 72 | [server:broadcast] |
| 72 | | use = egg:Paste#http |
| | 73 | use = egg:waitress#main |
| 73 | 74 | host = 0.0.0.0 |
| 74 | 75 | port = 6543 |
| 75 | 76 | |
| … |
… |
host = %(fcgi_host)s
|
| 80 | 81 | port = %(fcgi_port)s |
| 81 | 82 | |
| 82 | 83 | [server:http] |
| 83 | | use = egg:Paste#http |
| | 84 | use = egg:waitress#main |
| 84 | 85 | host = %(http_host)s |
| 85 | 86 | port = %(http_port)s |
diff --git a/setup.py b/setup.py
index 96325ff..e71f3af 100644
|
a
|
b
|
def get_version():
|
| 43 | 43 | pyversion_install_requires = [] |
| 44 | 44 | if PY2: |
| 45 | 45 | pyversion_install_requires.append('argparse') # only for < 2.7 |
| 46 | | pyversion_install_requires.append('PasteScript') |
| 47 | 46 | # newer sqlalchemy-migrate requires pbr which BREAKS EVERYTHING AND IS |
| 48 | 47 | # TERRIBLE AND IS THE END OF ALL THINGS |
| 49 | 48 | # I'd love to remove this restriction. |
| … |
… |
if PY2:
|
| 55 | 54 | pyversion_install_requires.append('mock==1.0.1') # mock is in the stdlib for 3.3+ |
| 56 | 55 | # PyPI version (1.4.2) does not have proper Python 3 support |
| 57 | 56 | pyversion_install_requires.append('ExifRead') |
| 58 | | pyversion_install_requires.append('PasteScript') |
| 59 | | pyversion_install_requires.append('Paste') |
| 60 | | else: |
| 61 | | pyversion_install_requires.append('gunicorn') |
| 62 | 57 | |
| 63 | 58 | install_requires = [ |
| | 59 | 'waitress', |
| 64 | 60 | 'alembic==0.6.6', |
| 65 | 61 | 'python-dateutil', |
| 66 | 62 | 'wtforms', |