Skip to content

Commit 2f8a0ca

Browse files
committed
run lifespan in same loop
1 parent e2cfd96 commit 2f8a0ca

File tree

2 files changed

+46
-48
lines changed

2 files changed

+46
-48
lines changed

src/socketify/asgi.py

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -613,94 +613,93 @@ def listen(self, port_or_options, handler=None):
613613
self.SERVER_HOST = (
614614
"0.0.0.0" if isinstance(port_or_options, int) else port_or_options.host
615615
)
616-
self.server.listen(port_or_options, handler)
617-
return self
618-
619-
def run(self):
620616
if not self.lifespan:
621-
self.server.run()
617+
self.server.listen(port_or_options, handler)
622618
return self
623-
619+
624620
scope = {"type": "lifespan", "asgi": {"version": "3.0", "spec_version": "2.3"}}
625621

626-
lifespan_loop = Loop(lambda loop, error, response: logging.error("Uncaught Exception: %s" % str(error)))
627-
is_starting = True
628-
is_stopped = False
629-
status = 0 # 0 starting, 1 ok, 2 error, 3 stoping, 4 stopped, 5 stopped with error, 6 no lifespan
630-
status_message = ""
631-
stop_future = lifespan_loop.create_future()
622+
asgi_app = self
623+
self.is_starting = True
624+
self.is_stopped = False
625+
self.status = 0 # 0 starting, 1 ok, 2 error, 3 stoping, 4 stopped, 5 stopped with error, 6 no lifespan
626+
self.status_message = ""
627+
self.stop_future = self.server.loop.create_future()
628+
632629
async def send(options):
633-
nonlocal status, status_message, is_stopped
630+
nonlocal asgi_app
634631
type = options["type"]
635-
status_message = options.get("message", "")
632+
asgi_app.status_message = options.get("message", "")
636633
if type == "lifespan.startup.complete":
637-
status = 1
634+
asgi_app.status = 1
635+
asgi_app.server.listen(port_or_options, handler)
638636
elif type == "lifespan.startup.failed":
639-
is_stopped = True
640-
status = 2
637+
asgi_app.is_stopped = True
638+
asgi_app.status = 2
641639
elif type == "lifespan.shutdown.complete":
642-
is_stopped = True
643-
status = 4
640+
asgi_app.is_stopped = True
641+
asgi_app.status = 4
644642
elif type == "lifespan.shutdown.failed":
645-
is_stopped = True
646-
status = 5
643+
asgi_app.is_stopped = True
644+
asgi_app.status = 5
647645

648646
async def receive():
649-
nonlocal is_starting, is_stopped
650-
while not is_stopped:
651-
if is_starting:
652-
is_starting = False
647+
nonlocal asgi_app
648+
while not asgi_app.is_stopped:
649+
if asgi_app.is_starting:
650+
asgi_app.is_starting = False
653651
return {
654652
"type": "lifespan.startup",
655653
"asgi": {"version": "3.0", "spec_version": "2.3"},
656654
}
657-
return await stop_future
655+
return await asgi_app.stop_future
658656

659657
async def task_wrapper(task):
660-
nonlocal status
658+
nonlocal asgi_app
661659
try:
662660
return await task
663661
except Exception as error:
664662
try:
665663
# just log in console the error to call attention
666664
logging.error("Uncaught Exception: %s" % str(error))
667-
status = 6 # no more lifespan
665+
if asgi_app.status < 2:
666+
asgi_app.status = 6 # no more lifespan
667+
asgi_app.server.listen(port_or_options, handler)
668668
finally:
669669
return None
670670

671671
# start lifespan
672-
lifespan_loop.ensure_future(task_wrapper(self.app(scope, receive, send)))
673-
674-
# run until start or fail
675-
while status == 0:
676-
lifespan_loop.run_once()
677-
672+
self.server.loop.ensure_future(task_wrapper(self.app(scope, receive, send)))
673+
self.server.run()
678674
# failed to start
679-
if status == 2:
680-
logging.error("Startup failed: %s" % str(status_message))
675+
if self.status == 2:
676+
logging.error("Startup failed: %s" % str(self.status_message))
677+
return self
678+
return self
679+
680+
def run(self):
681+
if not self.lifespan:
682+
self.server.run()
681683
return self
682684

683685
# run app
684686
self.server.run()
685-
686687
# no more lifespan events
687-
if status == 6:
688+
if self.status == 6:
688689
return self
689-
690690
# signal stop
691-
status = 3
692-
stop_future.set_result({
691+
self.status = 3
692+
self.stop_future.set_result({
693693
"type": "lifespan.shutdown",
694694
"asgi": {"version": "3.0", "spec_version": "2.3"},
695695
})
696-
697696
# run until end or fail
698-
while status == 3:
699-
lifespan_loop.run_once()
697+
while self.status == 3:
698+
self.server.loop.run_once()
700699

701700
# failed to stop
702-
if status == 5:
703-
logging.error("Shutdown failed: %s" % str(status_message))
701+
if self.status == 5:
702+
logging.error("Shutdown failed: %s" % str(self.status_message))
704703
return self
705704

706705
def __del__(self):

src/socketify/cli.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ def execute(args):
170170
host = options.get("--host", options.get("-h", "127.0.0.1"))
171171
uds = options.get('--uds', None)
172172
lifespan = options.get('--lifespan', "auto")
173-
lifespan=False if lifespan == "off" or lifespan is not True else True
174-
173+
lifespan = False if lifespan == "off" else True
175174
task_factory_maxitems = int(options.get("--task-factory-maxitems", 100000))
176175

177176
disable_listen_log = options.get("--disable-listen-log", False)

0 commit comments

Comments
 (0)