Fix Plex setup race condition v2 (#28943)

* Connect websocket when platforms ready, not when HA is ready

* Use callbacks from platform setup tasks instead

* Convert setup to async

* Apply suggestions from code review

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
jjlawren 2019-11-23 09:16:21 -06:00 committed by GitHub
parent 614842bcf2
commit 2c00a9ec68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 15 deletions

View file

@ -1,5 +1,6 @@
"""Support to embed Plex."""
import asyncio
import functools
import logging
import plexapi.exceptions
@ -16,7 +17,6 @@ from homeassistant.const import (
CONF_TOKEN,
CONF_URL,
CONF_VERIFY_SSL,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.helpers import config_validation as cv
@ -37,6 +37,7 @@ from .const import (
DISPATCHERS,
DOMAIN as PLEX_DOMAIN,
PLATFORMS,
PLATFORMS_COMPLETED,
PLEX_MEDIA_PLAYER_OPTIONS,
PLEX_SERVER_CONFIG,
PLEX_UPDATE_PLATFORMS_SIGNAL,
@ -72,18 +73,21 @@ CONFIG_SCHEMA = vol.Schema({PLEX_DOMAIN: SERVER_CONFIG_SCHEMA}, extra=vol.ALLOW_
_LOGGER = logging.getLogger(__package__)
def setup(hass, config):
async def async_setup(hass, config):
"""Set up the Plex component."""
hass.data.setdefault(PLEX_DOMAIN, {SERVERS: {}, DISPATCHERS: {}, WEBSOCKETS: {}})
hass.data.setdefault(
PLEX_DOMAIN,
{SERVERS: {}, DISPATCHERS: {}, WEBSOCKETS: {}, PLATFORMS_COMPLETED: {}},
)
plex_config = config.get(PLEX_DOMAIN, {})
if plex_config:
_setup_plex(hass, plex_config)
_async_setup_plex(hass, plex_config)
return True
def _setup_plex(hass, config):
def _async_setup_plex(hass, config):
"""Pass configuration to a config flow."""
server_config = dict(config)
if MP_DOMAIN in server_config:
@ -141,11 +145,7 @@ async def async_setup_entry(hass, entry):
)
server_id = plex_server.machine_identifier
hass.data[PLEX_DOMAIN][SERVERS][server_id] = plex_server
for platform in PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
)
hass.data[PLEX_DOMAIN][PLATFORMS_COMPLETED][server_id] = set()
entry.add_update_listener(async_options_updated)
@ -167,19 +167,25 @@ async def async_setup_entry(hass, entry):
)
hass.data[PLEX_DOMAIN][WEBSOCKETS][server_id] = websocket
async def async_start_websocket_session(_):
await websocket.listen()
def start_websocket_session(platform, _):
hass.data[PLEX_DOMAIN][PLATFORMS_COMPLETED][server_id].add(platform)
if hass.data[PLEX_DOMAIN][PLATFORMS_COMPLETED][server_id] == PLATFORMS:
hass.loop.create_task(websocket.listen())
def close_websocket_session(_):
websocket.close()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, async_start_websocket_session)
unsub = hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, close_websocket_session
)
hass.data[PLEX_DOMAIN][DISPATCHERS][server_id].append(unsub)
for platform in PLATFORMS:
task = hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
)
task.add_done_callback(functools.partial(start_websocket_session, platform))
return True

View file

@ -9,7 +9,8 @@ DEFAULT_SSL = False
DEFAULT_VERIFY_SSL = True
DISPATCHERS = "dispatchers"
PLATFORMS = ["media_player", "sensor"]
PLATFORMS = frozenset(["media_player", "sensor"])
PLATFORMS_COMPLETED = "platforms_completed"
SERVERS = "servers"
WEBSOCKETS = "websockets"