fix race condition
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 3 Apr 2023 21:57:44 +0000 (23:57 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Mon, 3 Apr 2023 21:57:44 +0000 (23:57 +0200)
music_assistant/server/controllers/media/albums.py
music_assistant/server/controllers/media/artists.py
music_assistant/server/controllers/media/playlists.py
music_assistant/server/controllers/media/radio.py
music_assistant/server/controllers/media/tracks.py

index f9e57856f0391ac38fbd9fd4766b42b7b887aff0..f9a76170a73fee0fa2015d4402ce336cc3ce190f 100644 (file)
@@ -236,9 +236,9 @@ class AlbumsController(MediaControllerBase[Album]):
                 },
             )
             item_id = new_item["item_id"]
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, item.provider_mappings)
-        self.logger.debug("added %s to database", item.name)
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, item.provider_mappings)
+            self.logger.debug("added %s to database", item.name)
         # return created object
         return await self.get_db_item(item_id)
 
@@ -257,28 +257,28 @@ class AlbumsController(MediaControllerBase[Album]):
         else:
             album_type = cur_item.album_type
         sort_artist = album_artists[0].sort_name if album_artists else ""
-
-        await self.mass.music.database.update(
-            self.db_table,
-            {"item_id": item_id},
-            {
-                "name": item.name if overwrite else cur_item.name,
-                "sort_name": item.sort_name if overwrite else cur_item.sort_name,
-                "sort_artist": sort_artist,
-                "version": item.version if overwrite else cur_item.version,
-                "year": item.year if overwrite else cur_item.year or item.year,
-                "barcode": ";".join(cur_item.barcode),
-                "album_type": album_type.value,
-                "artists": serialize_to_json(album_artists) or None,
-                "metadata": serialize_to_json(metadata),
-                "provider_mappings": serialize_to_json(provider_mappings),
-                "musicbrainz_id": item.musicbrainz_id or cur_item.musicbrainz_id,
-                "timestamp_modified": int(utc_timestamp()),
-            },
-        )
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, provider_mappings)
-        self.logger.debug("updated %s in database: %s", item.name, item_id)
+        async with self._db_add_lock:
+            await self.mass.music.database.update(
+                self.db_table,
+                {"item_id": item_id},
+                {
+                    "name": item.name if overwrite else cur_item.name,
+                    "sort_name": item.sort_name if overwrite else cur_item.sort_name,
+                    "sort_artist": sort_artist,
+                    "version": item.version if overwrite else cur_item.version,
+                    "year": item.year if overwrite else cur_item.year or item.year,
+                    "barcode": ";".join(cur_item.barcode),
+                    "album_type": album_type.value,
+                    "artists": serialize_to_json(album_artists) or None,
+                    "metadata": serialize_to_json(metadata),
+                    "provider_mappings": serialize_to_json(provider_mappings),
+                    "musicbrainz_id": item.musicbrainz_id or cur_item.musicbrainz_id,
+                    "timestamp_modified": int(utc_timestamp()),
+                },
+            )
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, provider_mappings)
+            self.logger.debug("updated %s in database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _get_provider_album_tracks(
index d0ddc7ba1b3595a62dde0a2c470631bbe90181d8..d88831e03f96587ad11dbac7f917547bed88b14a 100644 (file)
@@ -315,9 +315,9 @@ class ArtistsController(MediaControllerBase[Artist]):
         async with self._db_add_lock:
             new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
             item_id = new_item["item_id"]
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, item.provider_mappings)
-        self.logger.debug("added %s to database", item.name)
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, item.provider_mappings)
+            self.logger.debug("added %s to database", item.name)
         # return created object
         return await self.get_db_item(item_id)
 
@@ -336,22 +336,22 @@ class ArtistsController(MediaControllerBase[Artist]):
                 item.musicbrainz_id = VARIOUS_ARTISTS_ID
             if item.musicbrainz_id == VARIOUS_ARTISTS_ID:
                 item.name = VARIOUS_ARTISTS
-
-        await self.mass.music.database.update(
-            self.db_table,
-            {"item_id": item_id},
-            {
-                "name": item.name if overwrite else cur_item.name,
-                "sort_name": item.sort_name if overwrite else cur_item.sort_name,
-                "musicbrainz_id": musicbrainz_id,
-                "metadata": serialize_to_json(metadata),
-                "provider_mappings": serialize_to_json(provider_mappings),
-                "timestamp_modified": int(utc_timestamp()),
-            },
-        )
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, provider_mappings)
-        self.logger.debug("updated %s in database: %s", item.name, item_id)
+        async with self._db_add_lock:
+            await self.mass.music.database.update(
+                self.db_table,
+                {"item_id": item_id},
+                {
+                    "name": item.name if overwrite else cur_item.name,
+                    "sort_name": item.sort_name if overwrite else cur_item.sort_name,
+                    "musicbrainz_id": musicbrainz_id,
+                    "metadata": serialize_to_json(metadata),
+                    "provider_mappings": serialize_to_json(provider_mappings),
+                    "timestamp_modified": int(utc_timestamp()),
+                },
+            )
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, provider_mappings)
+            self.logger.debug("updated %s in database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _get_provider_dynamic_tracks(
index cd3b1a91ebc51dcd4ec5f8d54b0ded72ee11eff3..007aded01ad3c7e8d4bfa643f5cb811cb1e8d575 100644 (file)
@@ -203,9 +203,9 @@ class PlaylistController(MediaControllerBase[Playlist]):
         async with self._db_add_lock:
             new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
             item_id = new_item["item_id"]
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, item.provider_mappings)
-        self.logger.debug("added %s to database", item.name)
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, item.provider_mappings)
+            self.logger.debug("added %s to database", item.name)
         # return created object
         return await self.get_db_item(item_id)
 
@@ -216,23 +216,24 @@ class PlaylistController(MediaControllerBase[Playlist]):
         cur_item = await self.get_db_item(item_id)
         metadata = cur_item.metadata.update(getattr(item, "metadata", None), overwrite)
         provider_mappings = self._get_provider_mappings(cur_item, item, overwrite)
-        await self.mass.music.database.update(
-            self.db_table,
-            {"item_id": item_id},
-            {
-                # always prefer name/owner from updated item here
-                "name": item.name or cur_item.name,
-                "sort_name": item.sort_name or cur_item.sort_name,
-                "owner": item.owner or cur_item.sort_name,
-                "is_editable": item.is_editable,
-                "metadata": serialize_to_json(metadata),
-                "provider_mappings": serialize_to_json(provider_mappings),
-                "timestamp_modified": int(utc_timestamp()),
-            },
-        )
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, provider_mappings)
-        self.logger.debug("updated %s in database: %s", item.name, item_id)
+        async with self._db_add_lock:
+            await self.mass.music.database.update(
+                self.db_table,
+                {"item_id": item_id},
+                {
+                    # always prefer name/owner from updated item here
+                    "name": item.name or cur_item.name,
+                    "sort_name": item.sort_name or cur_item.sort_name,
+                    "owner": item.owner or cur_item.sort_name,
+                    "is_editable": item.is_editable,
+                    "metadata": serialize_to_json(metadata),
+                    "provider_mappings": serialize_to_json(provider_mappings),
+                    "timestamp_modified": int(utc_timestamp()),
+                },
+            )
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, provider_mappings)
+            self.logger.debug("updated %s in database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _get_provider_playlist_tracks(
index 4ab8678298dc9460faa84eb7e5a234a682bfc975..2779298b5b95fbfe82a6c1e5fdf7c5163b0deb08 100644 (file)
@@ -89,9 +89,9 @@ class RadioController(MediaControllerBase[Radio]):
         async with self._db_add_lock:
             new_item = await self.mass.music.database.insert(self.db_table, item.to_db_row())
             item_id = new_item["item_id"]
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, item.provider_mappings)
-        self.logger.debug("added %s to database", item.name)
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, item.provider_mappings)
+            self.logger.debug("added %s to database", item.name)
         # return created object
         return await self.get_db_item(item_id)
 
@@ -101,21 +101,22 @@ class RadioController(MediaControllerBase[Radio]):
         metadata = cur_item.metadata.update(getattr(item, "metadata", None), overwrite)
         provider_mappings = self._get_provider_mappings(cur_item, item, overwrite)
         match = {"item_id": item_id}
-        await self.mass.music.database.update(
-            self.db_table,
-            match,
-            {
-                # always prefer name from updated item here
-                "name": item.name or cur_item.name,
-                "sort_name": item.sort_name or cur_item.sort_name,
-                "metadata": serialize_to_json(metadata),
-                "provider_mappings": serialize_to_json(provider_mappings),
-                "timestamp_modified": int(utc_timestamp()),
-            },
-        )
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, provider_mappings)
-        self.logger.debug("updated %s in database: %s", item.name, item_id)
+        async with self._db_add_lock:
+            await self.mass.music.database.update(
+                self.db_table,
+                match,
+                {
+                    # always prefer name from updated item here
+                    "name": item.name or cur_item.name,
+                    "sort_name": item.sort_name or cur_item.sort_name,
+                    "metadata": serialize_to_json(metadata),
+                    "provider_mappings": serialize_to_json(provider_mappings),
+                    "timestamp_modified": int(utc_timestamp()),
+                },
+            )
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, provider_mappings)
+            self.logger.debug("updated %s in database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _get_provider_dynamic_tracks(
index 47d982f0e50af4783c1906092dacd3a7386aec86..571f15fb725c8373ee90a608cc4ac5ec3a2282e4 100644 (file)
@@ -319,10 +319,10 @@ class TracksController(MediaControllerBase[Track]):
                 },
             )
             item_id = new_item["item_id"]
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, item.provider_mappings)
-        # return created object
-        self.logger.debug("added %s to database: %s", item.name, item_id)
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, item.provider_mappings)
+            # return created object
+            self.logger.debug("added %s to database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _update_db_item(
@@ -336,25 +336,26 @@ class TracksController(MediaControllerBase[Track]):
             cur_item.isrc.update(item.isrc)
         track_artists = await self._get_artist_mappings(cur_item, item)
         track_albums = await self._get_track_albums(cur_item, item)
-        await self.mass.music.database.update(
-            self.db_table,
-            {"item_id": item_id},
-            {
-                "name": item.name or cur_item.name,
-                "sort_name": item.sort_name or cur_item.sort_name,
-                "version": item.version or cur_item.version,
-                "duration": getattr(item, "duration", None) or cur_item.duration,
-                "artists": serialize_to_json(track_artists),
-                "albums": serialize_to_json(track_albums),
-                "metadata": serialize_to_json(metadata),
-                "provider_mappings": serialize_to_json(provider_mappings),
-                "isrc": ";".join(cur_item.isrc),
-                "timestamp_modified": int(utc_timestamp()),
-            },
-        )
-        # update/set provider_mappings table
-        await self._set_provider_mappings(item_id, provider_mappings)
-        self.logger.debug("updated %s in database: %s", item.name, item_id)
+        async with self._db_add_lock:
+            await self.mass.music.database.update(
+                self.db_table,
+                {"item_id": item_id},
+                {
+                    "name": item.name or cur_item.name,
+                    "sort_name": item.sort_name or cur_item.sort_name,
+                    "version": item.version or cur_item.version,
+                    "duration": getattr(item, "duration", None) or cur_item.duration,
+                    "artists": serialize_to_json(track_artists),
+                    "albums": serialize_to_json(track_albums),
+                    "metadata": serialize_to_json(metadata),
+                    "provider_mappings": serialize_to_json(provider_mappings),
+                    "isrc": ";".join(cur_item.isrc),
+                    "timestamp_modified": int(utc_timestamp()),
+                },
+            )
+            # update/set provider_mappings table
+            await self._set_provider_mappings(item_id, provider_mappings)
+            self.logger.debug("updated %s in database: %s", item.name, item_id)
         return await self.get_db_item(item_id)
 
     async def _get_track_albums(