[elbe-devel] [PATCH 5/6] elbepack: daemon: remove cherrypy usage
Thomas Weißschuh
thomas.weissschuh at linutronix.de
Tue Jun 25 16:25:37 CEST 2024
Only WSGI server from cherrypy is used.
And through private APIs at that.
Switch to the stdlib WSGI server.
While it is single-threaded, so is the elbe initvm itself.
In case multithreading is needed in the future it is still possible to
switch either to ThreadingHTTPServer or even a dedicated WSGI server
library.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
elbepack/commands/daemon.py | 59 ++++++++++++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 19 deletions(-)
diff --git a/elbepack/commands/daemon.py b/elbepack/commands/daemon.py
index 08b396eb043f..af15da5923f2 100644
--- a/elbepack/commands/daemon.py
+++ b/elbepack/commands/daemon.py
@@ -4,14 +4,41 @@
import contextlib
import importlib
+import wsgiref.simple_server
from optparse import OptionParser
from pkgutil import iter_modules
-import cherrypy
-
import elbepack.daemons
+def _not_found(start_response):
+ start_response('404 Not Found', [('Content-Type', 'text/plain')])
+ return [b'not found']
+
+
+class _WsgiDispatcher:
+ def __init__(self, mapping):
+ self.mapping = mapping
+
+ def __call__(self, environ, start_response):
+ path_info = environ['PATH_INFO']
+ parts = path_info.split('/', maxsplit=2)
+ if len(parts) != 3:
+ return _not_found(start_response)
+ _, app_name, _ = parts
+
+ app = self.mapping.get(app_name)
+ if app is None:
+ return _not_found(start_response)
+
+ return app(environ, start_response)
+
+
+class _ElbeWSGIRequestHandler(wsgiref.simple_server.WSGIRequestHandler):
+ def log_request(self, *args, **kargs):
+ pass # Noop
+
+
def get_daemonlist():
return [x for _, x, _ in iter_modules(elbepack.daemons.__path__)]
@@ -36,6 +63,8 @@ def run_command(argv):
(opt, _) = oparser.parse_args(argv)
with contextlib.ExitStack() as stack:
+ mapping = {}
+
for d in daemons:
print(f'enable {d}')
module = 'elbepack.daemons.' + str(d)
@@ -43,20 +72,12 @@ def run_command(argv):
app = cmdmod.get_app()
if hasattr(app, 'stop'):
stack.callback(app.stop)
- cherrypy.tree.graft(app, '/' + str(d))
-
- cherrypy.server.unsubscribe()
- server = cherrypy._cpserver.Server()
- server.socket_host = opt.host
- server.socket_port = opt.port
- server.thread_pool = 30
-
- # For SSL Support
- # server.ssl_module = 'pyopenssl'
- # server.ssl_certificate = 'ssl/certificate.crt'
- # server.ssl_private_key = 'ssl/private.key'
- # server.ssl_certificate_chain = 'ssl/bundle.crt'
-
- server.subscribe()
- cherrypy.engine.start()
- cherrypy.engine.block()
+ mapping[d] = app
+
+ dispatcher = _WsgiDispatcher(mapping)
+
+ with wsgiref.simple_server.make_server(
+ opt.host, opt.port, dispatcher,
+ handler_class=_ElbeWSGIRequestHandler,
+ ) as httpd:
+ httpd.serve_forever()
--
2.45.2
More information about the elbe-devel
mailing list