Skip to content

Commit 9258295

Browse files
committed
Fix thread leak in SessionShutdownObserver and WebRtcWorker
1 parent 5e43a3d commit 9258295

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

streamlit_webrtc/shutdown.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,36 @@ def _polling_thread_impl(
3838
app_session_ref: "weakref.ReferenceType[AppSession]",
3939
callback: Callback,
4040
):
41-
# Use polling because event-based methods are not available
42-
# to observe the session lifecycle.
4341
while True:
4442
app_session = app_session_ref()
4543
if not app_session:
46-
logger.debug("AppSession has removed.")
44+
logger.debug("AppSession has been removed.")
4745
break
4846
if app_session._state == AppSessionState.SHUTDOWN_REQUESTED:
49-
logger.debug(
50-
"AppSession %s has been requested to shutdown.",
51-
app_session.id,
52-
)
47+
logger.debug("AppSession %s shutdown requested.", app_session.id)
5348
break
5449
if self._polling_thread_stop_event.wait(1.0):
55-
logger.debug(
56-
"The polling thread should be stopped. Exit the polling loop and return."
57-
)
50+
logger.debug("Polling thread stop requested. Exiting loop.")
5851
return
5952

60-
# Ensure the flag is set
6153
self._polling_thread_stop_event.set()
62-
63-
logger.debug("AppSession shutdown has been detected.")
54+
logger.debug("AppSession shutdown detected.")
6455
callback()
6556

66-
def stop(self):
67-
if self._polling_thread_stop_event.is_set():
57+
def stop(self, timeout: float = 1.0) -> None:
58+
"""
59+
Stop the polling thread cleanly so we don't leak ShutdownPolling_* threads.
60+
"""
61+
if not self._polling_thread:
6862
return
6963

70-
if self._polling_thread:
71-
self._polling_thread_stop_event.set()
72-
self._polling_thread.join()
73-
self._polling_thread = None
64+
self._polling_thread_stop_event.set()
65+
66+
if self._polling_thread.is_alive():
67+
try:
68+
self._polling_thread.join(timeout=timeout)
69+
except Exception:
70+
logger.exception("Failed to join ShutdownPolling thread")
71+
72+
self._polling_thread = None
73+

streamlit_webrtc/webrtc.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -542,19 +542,10 @@ def on_track_created(track_type: TrackType, track: MediaStreamTrack):
542542
async def on_iceconnectionstatechange():
543543
logger.debug("ICE connection state is %s", self.pc.iceConnectionState)
544544
iceConnectionState = self.pc.iceConnectionState
545-
546-
if iceConnectionState in ("failed","disconnect","closed"):
547-
self._unset_processors()
548-
if iceConnectionState in ("failed","disconnect","closed"):
549-
try:
550-
if self.pc and self.pc.connectionState != "closed":
551-
await self.pc.close()
552-
except Exception as e:
553-
logger.debug("Error occurred while closing the peer connection", e)
554-
555-
if self._session_shutdown_observer:
556-
self._session_shutdown_observer.stop()
557-
545+
546+
if iceConnectionState in ("closed", "failed", "disconnected"):
547+
logger.debug("Connection state is %s, stopping worker", iceConnectionState)
548+
self.stop()
558549

559550

560551

0 commit comments

Comments
 (0)