annotate piecrust/serving/wrappers.py @ 738:b91fe30ae7aa

internal: Remove threading stuff we don't need anymore.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 02 Jun 2016 13:00:36 -0700
parents 81d9c3a3a0b5
children 4850f8c21b6e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import os
558
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
2 import signal
552
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
3 import logging
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
4 import urllib.request
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
5
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
6
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
7 logger = logging.getLogger(__name__)
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
10 def run_werkzeug_server(appfactory, host, port,
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11 use_debugger=False, use_reloader=False):
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12 from werkzeug.serving import run_simple
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 def _run_sse_check():
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 # We don't want to run the processing loop here if this isn't
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16 # the actual process that does the serving. In most cases it is,
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 # but if we're using Werkzeug's reloader, then it won't be the
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18 # first time we get there... it will only be the correct process
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19 # the second time, when the reloading process is spawned, with the
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20 # `WERKZEUG_RUN_MAIN` variable set.
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 return (not use_reloader or
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 os.environ.get('WERKZEUG_RUN_MAIN') == 'true')
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
24 app = _get_piecrust_server(appfactory,
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25 run_sse_check=_run_sse_check)
552
9612cfc6455a serve: Rewrite of the Server-Sent Event code for build notifications.
Ludovic Chabant <ludovic@chabant.com>
parents: 374
diff changeset
26
558
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
27 # We need to do a few things to get Werkzeug to properly shutdown or
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
28 # restart while SSE responses are running. This is because Werkzeug runs
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
29 # them in background threads (because we tell it to), but those threads
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
30 # are not marked as "daemon", so when the main thread tries to exit, it
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
31 # will wait on those SSE responses to end, which will pretty much never
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
32 # happen (except for a timeout or the user closing their browser).
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
33 #
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
34 # In theory we should be using a proper async server for this kind of
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
35 # stuff, but I'd rather avoid additional dependencies on stuff that's not
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
36 # necessarily super portable.
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
37 #
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
38 # Anyway, we run the server as usual, but we intercept the `SIGINT`
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
39 # signal for when the user presses `CTRL-C`. When that happens, we set a
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
40 # flag that will make all existing SSE loops return, which will make it
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
41 # possible for the main thread to end too.
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
42 #
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
43 # We also need to do a few thing for the "reloading" feature in Werkzeug,
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
44 # see the comment down there for more info.
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
45 def _shutdown_server():
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
46 from piecrust.serving import procloop
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
47 procloop.server_shutdown = True
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
48
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
49 def _shutdown_server_and_raise_sigint():
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
50 if not use_reloader or os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
51 # We only need to shutdown the SSE requests for the process
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
52 # that actually runs them.
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
53 print("")
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
54 print("Shutting server down...")
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
55 _shutdown_server()
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
56 raise KeyboardInterrupt()
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
57
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
58 signal.signal(signal.SIGINT,
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
59 lambda *args: _shutdown_server_and_raise_sigint())
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
60
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
61 try:
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
62 run_simple(host, port, app,
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
63 threaded=True,
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
64 use_debugger=use_debugger,
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
65 use_reloader=use_reloader)
558
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
66 except SystemExit:
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
67 if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
68 # When using the reloader, if code has changed, the child process
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
69 # will use `sys.exit` to end and let the master process restart
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
70 # it... we need to shutdown the SSE requests otherwise it will
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
71 # not exit.
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
72 _shutdown_server()
9ab005db2592 serve: Improve reloading and shutdown of the preview server.
Ludovic Chabant <ludovic@chabant.com>
parents: 553
diff changeset
73 raise
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
76 def run_gunicorn_server(appfactory, gunicorn_options=None):
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 from gunicorn.app.base import BaseApplication
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79 class PieCrustGunicornApplication(BaseApplication):
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 def __init__(self, app, options):
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81 self.app = app
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82 self.options = options
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 super(PieCrustGunicornApplication, self).__init__()
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
84
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
85 def load_config(self):
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
86 for k, v in self.options.items():
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
87 if k in self.cfg.settings and v is not None:
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
88 self.cfg.set(k, v)
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
89
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
90 def load(self):
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
91 return self.app
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
92
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
93 app = _get_piecrust_server(appfactory)
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
94
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
95 gunicorn_options = gunicorn_options or {}
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
96 app_wrapper = PieCrustGunicornApplication(app, gunicorn_options)
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
97 app_wrapper.run()
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
98
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
99
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
100 def _get_piecrust_server(appfactory, run_sse_check=None):
553
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents: 552
diff changeset
101 from piecrust.serving.middlewares import (
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents: 552
diff changeset
102 StaticResourcesMiddleware, PieCrustDebugMiddleware)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents: 552
diff changeset
103 from piecrust.serving.server import WsgiServer
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
104 app = WsgiServer(appfactory)
553
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents: 552
diff changeset
105 app = StaticResourcesMiddleware(app)
666
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
106 app = PieCrustDebugMiddleware(
81d9c3a3a0b5 internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents: 663
diff changeset
107 app, appfactory, run_sse_check=run_sse_check)
374
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
108 return app
fa3ee8a8ee2d serve: Split the server code in a couple modules inside a `serving` package.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109