Modify wait timeout in stream (#42794)

* Set wait timeout to 40

* Use dynamic wait_timeout

* Catch error in container open

* Get restart times from const.py

* Fix test_stream_keepalive
This commit is contained in:
uvjustin 2020-11-12 01:32:56 +08:00 committed by GitHub
parent f4f3192a6a
commit 66dccd86bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 4 deletions

View file

@ -23,3 +23,6 @@ MAX_TIMESTAMP_GAP = 10000 # seconds - anything from 10 to 50000 is probably rea
MAX_MISSING_DTS = 6 # Number of packets missing DTS to allow
STREAM_TIMEOUT = 30 # Timeout for reading stream
STREAM_RESTART_INCREMENT = 10 # Increase wait_timeout by this amount each retry
STREAM_RESTART_RESET_TIME = 300 # Reset wait_timeout after this many seconds

View file

@ -11,6 +11,8 @@ from .const import (
MAX_TIMESTAMP_GAP,
MIN_SEGMENT_DURATION,
PACKETS_TO_WAIT_FOR_AUDIO,
STREAM_RESTART_INCREMENT,
STREAM_RESTART_RESET_TIME,
STREAM_TIMEOUT,
)
from .core import Segment, StreamBuffer
@ -56,8 +58,13 @@ def stream_worker(hass, stream, quit_event):
_LOGGER.exception("Stream connection failed: %s", stream.source)
if not stream.keepalive or quit_event.is_set():
break
# To avoid excessive restarts, don't restart faster than once every 40 seconds.
wait_timeout = max(40 - (time.time() - start_time), 0)
# To avoid excessive restarts, wait before restarting
# As the required recovery time may be different for different setups, start
# with trying a short wait_timeout and increase it on each reconnection attempt.
# Reset the wait_timeout after the worker has been up for several minutes
if time.time() - start_time > STREAM_RESTART_RESET_TIME:
wait_timeout = 0
wait_timeout += STREAM_RESTART_INCREMENT
_LOGGER.debug(
"Restarting stream worker in %d seconds: %s",
wait_timeout,
@ -68,7 +75,13 @@ def stream_worker(hass, stream, quit_event):
def _stream_worker_internal(hass, stream, quit_event):
"""Handle consuming streams."""
container = av.open(stream.source, options=stream.options, timeout=STREAM_TIMEOUT)
try:
container = av.open(
stream.source, options=stream.options, timeout=STREAM_TIMEOUT
)
except av.AVError:
_LOGGER.error("Error opening stream %s", stream.source)
return
try:
video_stream = container.streams.video[0]
except (KeyError, IndexError):

View file

@ -147,7 +147,9 @@ async def test_stream_keepalive(hass):
with patch("av.open") as av_open, patch(
"homeassistant.components.stream.worker.time"
) as mock_time:
) as mock_time, patch(
"homeassistant.components.stream.worker.STREAM_RESTART_INCREMENT", 0
):
av_open.side_effect = av.error.InvalidDataError(-2, "error")
mock_time.time.side_effect = time_side_effect
# Request stream