Add a lock on nest stream URL creation to avoid multiple in flight at once (#63212)

Add a lock to avoid multiple calls to create stream URLs when requests race in parallel
to open streams. This is to avoid # of API calls on the nest server which can be
rate limited, and to avoid any possibility of having too many streams per camera outstanding at once.
This commit is contained in:
Allen Porter 2022-01-04 12:27:56 -08:00 committed by GitHub
parent 5c8e802cbf
commit cb76a30233
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,7 @@
"""Support for Google Nest SDM Cameras.""" """Support for Google Nest SDM Cameras."""
from __future__ import annotations from __future__ import annotations
import asyncio
from collections.abc import Callable from collections.abc import Callable
import datetime import datetime
import logging import logging
@ -74,6 +75,7 @@ class NestCamera(Camera):
self._device = device self._device = device
self._device_info = NestDeviceInfo(device) self._device_info = NestDeviceInfo(device)
self._stream: RtspStream | None = None self._stream: RtspStream | None = None
self._create_stream_url_lock = asyncio.Lock()
self._stream_refresh_unsub: Callable[[], None] | None = None self._stream_refresh_unsub: Callable[[], None] | None = None
# Cache of most recent event image # Cache of most recent event image
self._event_id: str | None = None self._event_id: str | None = None
@ -140,13 +142,14 @@ class NestCamera(Camera):
trait = self._device.traits[CameraLiveStreamTrait.NAME] trait = self._device.traits[CameraLiveStreamTrait.NAME]
if StreamingProtocol.RTSP not in trait.supported_protocols: if StreamingProtocol.RTSP not in trait.supported_protocols:
return None return None
if not self._stream: async with self._create_stream_url_lock:
_LOGGER.debug("Fetching stream url") if not self._stream:
try: _LOGGER.debug("Fetching stream url")
self._stream = await trait.generate_rtsp_stream() try:
except ApiException as err: self._stream = await trait.generate_rtsp_stream()
raise HomeAssistantError(f"Nest API error: {err}") from err except ApiException as err:
self._schedule_stream_refresh() raise HomeAssistantError(f"Nest API error: {err}") from err
self._schedule_stream_refresh()
assert self._stream assert self._stream
if self._stream.expires_at < utcnow(): if self._stream.expires_at < utcnow():
_LOGGER.warning("Stream already expired") _LOGGER.warning("Stream already expired")