diff --git a/src/socketify/asgi.py b/src/socketify/asgi.py index c95583c..1625d7c 100644 --- a/src/socketify/asgi.py +++ b/src/socketify/asgi.py @@ -498,13 +498,15 @@ def asgi(ssl, response, info, user_data, aborted): class _ASGI: - def __init__(self, app, options=None, websocket=True, websocket_options=None, task_factory_max_items=100_000): + def __init__(self, app, options=None, websocket=True, websocket_options=None, task_factory_max_items=100_000, lifespan=True): self.server = App(options, task_factory_max_items=0) self.SERVER_PORT = None self.SERVER_HOST = "" self.SERVER_SCHEME = "https" if self.server.options else "http" self.SERVER_WS_SCHEME = "wss" if self.server.options else "ws" self.task_factory_max_items = task_factory_max_items + self.lifespan = lifespan + loop = self.server.loop.loop # ASGI do not use app.run_async to not add any overhead from socketify.py WebFramework # internally will still use custom task factory for pypy because of Loop @@ -614,6 +616,11 @@ class _ASGI: return self def run(self): + if not self.lifespan: + print("No lifespan!") + self.server.run() + return self + scope = {"type": "lifespan", "asgi": {"version": "3.0", "spec_version": "2.3"}} lifespan_loop = Loop(lambda loop, error, response: logging.error("Uncaught Exception: %s" % str(error))) @@ -712,6 +719,7 @@ class ASGI: websocket=True, websocket_options=None, task_factory_max_items=100_000, #default = 100k = +20mib in memory + lifespan=True ): self.app = app self.options = options @@ -719,6 +727,7 @@ class ASGI: self.websocket_options = websocket_options self.listen_options = None self.task_factory_max_items = task_factory_max_items + self.lifespan = lifespan def listen(self, port_or_options, handler=None): self.listen_options = (port_or_options, handler) diff --git a/src/socketify/cli.py b/src/socketify/cli.py index 9846fad..fc626df 100644 --- a/src/socketify/cli.py +++ b/src/socketify/cli.py @@ -169,6 +169,9 @@ def execute(args): port = int(options.get("--port", options.get("-p", 8000))) host = options.get("--host", options.get("-h", "127.0.0.1")) uds = options.get('--uds', None) + lifespan = options.get('--lifespan', "auto") + lifespan=False if lifespan == "off" or lifespan is not True else True + task_factory_maxitems = int(options.get("--task-factory-maxitems", 100000)) disable_listen_log = options.get("--disable-listen-log", False) @@ -239,6 +242,7 @@ def execute(args): return print("socketify interface must be callable with 1 parameter def run(app: App)") # run app with the settings desired def run_app(): + # Add lifespan when lifespan hooks are implemented fork_app = App(ssl_options, int(options.get("--req-res-factory-maxitems", 0)), int(options.get("--ws-factory-maxitems", 0)), task_factory_maxitems) module(fork_app) # call module factory @@ -271,6 +275,6 @@ def execute(args): else: if uds: - Interface(module,options=ssl_options, websocket=websockets, websocket_options=websocket_options, task_factory_max_items=task_factory_maxitems).listen(AppListenOptions(domain=uds), listen_log).run(workers=workers) + Interface(module,options=ssl_options, websocket=websockets, websocket_options=websocket_options, task_factory_max_items=task_factory_maxitems, lifespan=lifespan).listen(AppListenOptions(domain=uds), listen_log).run(workers=workers) else: - Interface(module,options=ssl_options, websocket=websockets, websocket_options=websocket_options, task_factory_max_items=task_factory_maxitems).listen(AppListenOptions(port=port, host=host), listen_log).run(workers=workers) + Interface(module,options=ssl_options, websocket=websockets, websocket_options=websocket_options, task_factory_max_items=task_factory_maxitems, lifespan=lifespan).listen(AppListenOptions(port=port, host=host), listen_log).run(workers=workers) diff --git a/src/socketify/socketify.py b/src/socketify/socketify.py index e1ac4a6..30a0840 100644 --- a/src/socketify/socketify.py +++ b/src/socketify/socketify.py @@ -591,6 +591,11 @@ def uws_generic_listen_handler(listen_socket, config, user_data): config.port = lib.us_socket_local_port(app.SSL, listen_socket) if hasattr(app, "_listen_handler") and hasattr(app._listen_handler, "__call__"): app.socket = listen_socket + host = "" + try: + host = ffi.string(config.host).decode("utf8") + except: + pass app._listen_handler( None @@ -599,7 +604,7 @@ def uws_generic_listen_handler(listen_socket, config, user_data): port=int(config.port), host=None if config.host == ffi.NULL or listen_socket == ffi.NULL - else ffi.string(config.host).decode("utf8"), + else host, options=int(config.options), ) ) diff --git a/src/socketify/wsgi.py b/src/socketify/wsgi.py index 8deb7ef..c0f82d2 100644 --- a/src/socketify/wsgi.py +++ b/src/socketify/wsgi.py @@ -313,13 +313,14 @@ class _WSGI: # "Public" WSGI interface to allow easy forks/workers class WSGI: - def __init__(self, app, options=None, websocket=None, websocket_options=None, task_factory_max_items=100_000): + def __init__(self, app, options=None, websocket=None, websocket_options=None, task_factory_max_items=100_000, lifespan=False): self.app = app self.options = options self.websocket = websocket self.websocket_options = websocket_options self.listen_options = None self.task_factory_max_items = task_factory_max_items + # lifespan is not supported in WSGI def listen(self, port_or_options, handler=None): self.listen_options = (port_or_options, handler)