2
2
import asyncio
3
3
import logging
4
4
import os
5
+ import signal
5
6
import hypercorn .config
6
7
import hypercorn .asyncio
7
8
10
11
11
12
logging .basicConfig (level = DEFAULT_LOG_LEVEL )
12
13
13
-
14
14
def serve (f ):
15
15
"""serve a function f by wrapping it in an ASGI web application
16
16
and starting. The function can be either a constructor for a functon
@@ -46,6 +46,7 @@ async def __call__(self, scope, receive, send):
46
46
class ASGIApplication ():
47
47
def __init__ (self , f ):
48
48
self .f = f
49
+ self .stop_event = asyncio .Event ()
49
50
# Inform the user via logs that defaults will be used for health
50
51
# endpoints if no matchin methods were provided.
51
52
if hasattr (self .f , "alive" ) is not True :
@@ -67,7 +68,18 @@ def serve(self):
67
68
cfg .bind = [os .getenv ('LISTEN_ADDRESS' , DEFAULT_LISTEN_ADDRESS )]
68
69
69
70
logging .debug (f"function starting on { cfg .bind } " )
70
- return asyncio .run (hypercorn .asyncio .serve (self , cfg ))
71
+ return asyncio .run (self ._serve (cfg ))
72
+
73
+ async def _serve (self , cfg ):
74
+ loop = asyncio .get_event_loop ()
75
+ loop .add_signal_handler (signal .SIGINT , self ._handle_signal )
76
+ loop .add_signal_handler (signal .SIGTERM , self ._handle_signal )
77
+
78
+ await hypercorn .asyncio .serve (self , cfg )
79
+
80
+ def _handle_signal (self ):
81
+ logging .info ("Signal received: initiating shutdown" )
82
+ self .stop_event .set ()
71
83
72
84
async def on_start (self ):
73
85
"""on_start handles the ASGI server start event, delegating control
@@ -82,8 +94,8 @@ async def on_stop(self):
82
94
self .f .stop ()
83
95
else :
84
96
logging .info ("function does not implement 'stop'. Skipping." )
97
+ self .stop_event .set ()
85
98
86
- # Register ASGIFunctoin as a callable ASGI Function
87
99
async def __call__ (self , scope , receive , send ):
88
100
if scope ['type' ] == 'lifespan' :
89
101
while True :
@@ -101,7 +113,7 @@ async def __call__(self, scope, receive, send):
101
113
# Assert request is HTTP
102
114
if scope ["type" ] != "http" :
103
115
await send_exception (send , 400 ,
104
- "Functions currenly only support ASGI/HTTP "
116
+ "Functions currently only support ASGI/HTTP "
105
117
f"connections. Got { scope ['type' ]} "
106
118
)
107
119
return
0 commit comments