Refactoring DeepgramSTT to use request to reconnect.

This commit is contained in:
filipi87
2026-04-15 13:21:12 -03:00
parent f3c454dc54
commit d263ad3c34

View File

@@ -443,6 +443,7 @@ class DeepgramSTTService(STTService):
self._connection = None self._connection = None
self._connection_task = None self._connection_task = None
self._connection_ready = asyncio.Event()
def can_generate_metrics(self) -> bool: def can_generate_metrics(self) -> bool:
"""Check if this service can generate processing metrics. """Check if this service can generate processing metrics.
@@ -452,6 +453,24 @@ class DeepgramSTTService(STTService):
""" """
return True return True
async def _do_reconnect(self):
"""Disconnect and reconnect to Deepgram, waiting until ready.
Called by ``STTService._reconnect()`` inside the reconnecting guard.
Unlike ``WebsocketSTTService``, Deepgram's ``_connect()`` only
launches a background task — the actual WebSocket handshake happens
asynchronously. This method waits for ``_connection_ready`` to be set
before returning so that buffered audio frames are replayed only after
the new connection can accept them.
Raises:
asyncio.TimeoutError: If the connection is not established within
05 seconds.
"""
await self._disconnect()
await self._connect()
await asyncio.wait_for(self._connection_ready.wait(), timeout=5.0)
async def _update_settings(self, delta: STTSettings) -> dict[str, Any]: async def _update_settings(self, delta: STTSettings) -> dict[str, Any]:
"""Apply a settings delta and reconnect if anything changed.""" """Apply a settings delta and reconnect if anything changed."""
changed = await super()._update_settings(delta) changed = await super()._update_settings(delta)
@@ -463,9 +482,7 @@ class DeepgramSTTService(STTService):
if isinstance(self._settings, self.Settings): if isinstance(self._settings, self.Settings):
self._settings._sync_extra_to_fields() self._settings._sync_extra_to_fields()
if self._connection: await self._request_reconnect()
await self._disconnect()
await self._connect()
return changed return changed
@@ -581,8 +598,11 @@ class DeepgramSTTService(STTService):
return return
logger.debug("Disconnecting from Deepgram") logger.debug("Disconnecting from Deepgram")
# Clear self._connection first to prevent run_stt from sending audio # Clear _connection and _connection_ready first to prevent run_stt
# during the close handshake, then close gracefully on the saved ref. # from sending audio during the close handshake, and to ensure any
# concurrent _do_reconnect() waiter sees a clean state before the
# new connection is established.
self._connection_ready.clear()
connection = self._connection connection = self._connection
self._connection = None self._connection = None
@@ -603,6 +623,7 @@ class DeepgramSTTService(STTService):
try: try:
async with self._client.listen.v1.connect(**connect_kwargs) as connection: async with self._client.listen.v1.connect(**connect_kwargs) as connection:
self._connection = connection self._connection = connection
self._connection_ready.set()
connection.on(EventType.MESSAGE, self._on_message) connection.on(EventType.MESSAGE, self._on_message)
connection.on(EventType.ERROR, self._on_error) connection.on(EventType.ERROR, self._on_error)
@@ -611,16 +632,15 @@ class DeepgramSTTService(STTService):
keepalive_task = self.create_task( keepalive_task = self.create_task(
self._keepalive_handler(), f"{self}::keepalive" self._keepalive_handler(), f"{self}::keepalive"
) )
try: await connection.start_listening()
await connection.start_listening()
finally:
await self.cancel_task(keepalive_task)
except asyncio.CancelledError: except asyncio.CancelledError:
raise raise
except Exception as e: except Exception as e:
logger.warning(f"{self}: Connection lost, will retry: {e}") logger.warning(f"{self}: Connection lost, will retry: {e}")
finally: finally:
self._connection_ready.clear()
self._connection = None self._connection = None
await self.cancel_task(keepalive_task)
async def _keepalive_handler(self): async def _keepalive_handler(self):
"""Periodically send KeepAlive frames to prevent server-side timeout. """Periodically send KeepAlive frames to prevent server-side timeout.