@@ -30,6 +30,47 @@ def get_name(coro: Any) -> str:
3030 )
3131
3232
33+ def patch_loop_close () -> None :
34+ """Patch loop.close to flush pending events before shutdown."""
35+ # Atexit shutdown hook happens after the event loop is closed.
36+ # Therefore, it is necessary to patch the loop.close method to ensure
37+ # that pending events are flushed before the interpreter shuts down.
38+ try :
39+ loop = asyncio .get_running_loop ()
40+ except RuntimeError :
41+ # No running loop → cannot patch now
42+ return
43+
44+ if getattr (loop , "_sentry_flush_patched" , False ):
45+ return
46+
47+ async def _flush () -> None :
48+ client = sentry_sdk .get_client ()
49+ if not client :
50+ return
51+
52+ try :
53+ if not isinstance (client .transport , AsyncHttpTransport ):
54+ return
55+
56+ task = client .close () # type: ignore
57+ if task is not None :
58+ await task
59+ except Exception :
60+ logger .warning ("Sentry flush failed during loop shutdown" , exc_info = True )
61+
62+ orig_close = loop .close
63+
64+ def _patched_close () -> None :
65+ try :
66+ loop .run_until_complete (_flush ())
67+ finally :
68+ orig_close ()
69+
70+ loop .close = _patched_close # type: ignore
71+ loop ._sentry_flush_patched = True # type: ignore
72+
73+
3374def patch_asyncio () -> None :
3475 orig_task_factory = None
3576 try :
@@ -125,46 +166,4 @@ class AsyncioIntegration(Integration):
125166 @staticmethod
126167 def setup_once () -> None :
127168 patch_asyncio ()
128-
129- def _patch_loop_close () -> None :
130- # Atexit shutdown hook happens after the event loop is closed.
131- # Therefore, it is necessary to patch the loop.close method to ensure
132- # that pending events are flushed before the interpreter shuts down.
133- try :
134- loop = asyncio .get_running_loop ()
135- except RuntimeError :
136- # No running loop → cannot patch now
137- return
138-
139- if getattr (loop , "_sentry_flush_patched" , False ):
140- return
141-
142- async def _flush () -> None :
143- client = sentry_sdk .get_client ()
144- if not client :
145- return
146- try :
147-
148- if not isinstance (client .transport , AsyncHttpTransport ):
149- return
150-
151- t = client .close () # type: ignore
152- if t is not None :
153- await t
154- except Exception :
155- logger .warning (
156- "Sentry flush failed during loop shutdown" , exc_info = True
157- )
158-
159- orig_close = loop .close
160-
161- def _patched_close () -> None :
162- try :
163- loop .run_until_complete (_flush ())
164- finally :
165- orig_close ()
166-
167- loop .close = _patched_close # type: ignore
168- loop ._sentry_flush_patched = True # type: ignore
169-
170- _patch_loop_close ()
169+ patch_loop_close ()
0 commit comments