fix race condition in adding players
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Fri, 5 Mar 2021 11:03:49 +0000 (12:03 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Fri, 5 Mar 2021 11:03:49 +0000 (12:03 +0100)
music_assistant/constants.py
music_assistant/managers/library.py
music_assistant/managers/players.py
music_assistant/mass.py
music_assistant/models/player_queue.py
music_assistant/providers/chromecast/__init__.py

index f218ece1ab730a5ff04ded7a79baeb44cc362dd7..c6b19ee2c62d6d268f7f2d95183f3c86f7b2a692 100755 (executable)
@@ -1,6 +1,6 @@
 """All constants for Music Assistant."""
 
-__version__ = "0.1.7"
+__version__ = "0.1.8"
 REQUIRED_PYTHON_VER = "3.8"
 
 # configuration keys/attributes
index 2e36adddadf99e5dc3ebbf9329db1925f8db9b01..ade46ab43655e1e41d1608dc670058b1762f85be 100755 (executable)
@@ -37,14 +37,14 @@ def sync_task(desc):
                         "Syncjob %s for provider %s is already running!", desc, prov_id
                     )
                     return
-            LOGGER.debug("Start syncjob %s for provider %s.", desc, prov_id)
+            LOGGER.info("Start syncjob %s for provider %s.", desc, prov_id)
             sync_job = (prov_id, desc)
             method_class.running_sync_jobs.add(sync_job)
             method_class.mass.signal_event(
                 EVENT_MUSIC_SYNC_STATUS, method_class.running_sync_jobs
             )
             await func(*args)
-            LOGGER.debug("Finished syncing %s for provider %s", desc, prov_id)
+            LOGGER.info("Finished syncing %s for provider %s", desc, prov_id)
             method_class.running_sync_jobs.remove(sync_job)
             method_class.mass.signal_event(
                 EVENT_MUSIC_SYNC_STATUS, method_class.running_sync_jobs
index bcb964c4657d488346457be94f16beeb9054f9ac..71bd79dd0edef79a52700d47c931ec5247bd21a8 100755 (executable)
@@ -163,37 +163,46 @@ class PlayerManager:
 
     async def add_player(self, player: Player) -> None:
         """Register a new player or update an existing one."""
+        player_id = player.player_id
+
         # guard for invalid data or exit in progress
         if not player or self.mass.exit:
             return
+
         # redirect to update if player is already added
-        if player.added_to_mass:
-            return await self.trigger_player_update(player.player_id)
-        # make sure that the mass instance is set on the player
-        player.mass = self.mass
-        self._players[player.player_id] = player
+        if player_id in self._players:
+            player = self._players[player_id]
+            if player.added_to_mass:
+                await self.trigger_player_update(player_id)
+                return
+        else:
+            self._players[player.player_id] = player
+            # make sure that the mass instance is set on the player
+            player.mass = self.mass
+
         # make sure that the player state is created/updated
         player.player_state.update(player.create_state())
+
         # Fully initialize only if player is enabled
-        if player.enabled:
-            await player.on_add()
-            player.added_to_mass = True
-            # create playerqueue instance
-            self._player_queues[player.player_id] = PlayerQueue(
-                self.mass, player.player_id
-            )
-            LOGGER.info(
-                "Player added: %s/%s",
-                player.provider_id,
-                player.name,
-            )
-            self.mass.signal_event(EVENT_PLAYER_ADDED, player)
-        else:
+        if not player.enabled:
             LOGGER.debug(
                 "Ignoring player: %s/%s because it's disabled",
                 player.provider_id,
                 player.name,
             )
+            return
+
+        # new player
+        player.added_to_mass = True
+        await player.on_add()
+        # create playerqueue instance
+        self._player_queues[player.player_id] = PlayerQueue(self.mass, player.player_id)
+        LOGGER.info(
+            "Player added: %s/%s",
+            player.provider_id,
+            player.name,
+        )
+        self.mass.signal_event(EVENT_PLAYER_ADDED, player)
 
     async def remove_player(self, player_id: str):
         """Remove a player from the registry."""
index d554d348ed0bf9f626093cf52c9b2e20a96faa74..49c50e363c23dd8ab5f3fba7fce2cd9f25618f17 100644 (file)
@@ -317,7 +317,12 @@ class MusicAssistant:
         while not self.exit:
             task = await self._background_tasks.get()
             await task
-            await asyncio.sleep(1)
+            if self._background_tasks.qsize() > 200:
+                await asyncio.sleep(0.5)
+            elif self._background_tasks.qsize() == 0:
+                await asyncio.sleep(10)
+            else:
+                await asyncio.sleep(1)
 
     async def setup_discovery(self) -> None:
         """Make this Music Assistant instance discoverable on the network."""
index 83e0496ccd4e38b45631202e19875495af0f08b7..f538cc5771346fad1079db5a14bf62f12eff6bf8 100755 (executable)
@@ -611,4 +611,4 @@ class PlayerQueue:
             "cur_index": self._cur_index,
         }
         await self.mass.cache.set(cache_str, cache_data)
-        LOGGER.info("queue state saved to file for player %s", self.queue_id)
+        LOGGER.debug("queue state saved to file for player %s", self.queue_id)
index a0041392526cb987c6761f069fb17319af8a78aa..155b503e3a3ddd96824dce25f5e2c79b407c40a6 100644 (file)
@@ -90,8 +90,8 @@ class ChromecastProvider(PlayerProvider):
             "Chromecast discovered: %s (%s)", cast_info.friendly_name, player_id
         )
         player = self.mass.players.get_player(player_id)
-        if not player and cast_info.is_audio_group:
-            # audio groups may reappear with new uuid, try to handle that
+        if not player:
+            # cast players may reappear with new uuid, try to handle that
             player = self.mass.players.get_player_by_name(
                 cast_info.friendly_name, PROV_ID
             )