Skip to content

add_entity_to_playlist event is not consistently being saved on the DB #1013

@hww-clementpoulain

Description

@hww-clementpoulain

Heya!

So we tested the following with both gazu 0.10.31 and 1.1.1.

The issue being that in some cases, if 5 entities are added to a playslit, 1 by 1, they may not be actually added and the final playlist may only have 3 entities reflected in it.
This is happening when multiple processes try to add different entity to the same playlist at the same time.
The assumed bug being a race condition as the whole playlist is updated when an entity is added.
Fix potentially need a change in both gazu and zou.

Code example to replicate the issue as a single user can be found at the bottom, including the output of 7 consecutive runs.
Create a playlist from Kitsu, assign a precise entity to it that is being kept at all time in the playlist and is not part of the script's entitiy id list.
After each run, clear the playlist of the added entities but leaving that one original entity present.
The re-queried playlist content at the end of each run output reflects what is being seen from the web interface every single time.

You will notice that the playlist object returned by each thread appears to be correct.
Only the re-queried playlist in its final state (and its reflection in Kitsu) is not.

from concurrent.futures import ThreadPoolExecutor
from datetime import datetime, timedelta

import gazu


def add_to_playlist(entity_id):
    while True:
        if datetime.now() - now > timedelta(seconds=7):
            new_playlist = gazu.playlist.add_entity_to_playlist(playlist, entity_id)
            print(f" Playlist updated, now has {len(new_playlist['shots'])} shots.")
            return new_playlist


# TODO: Set to host + login.
# TODO: Change for your IDs.

playlist_id = "d0c81a9f-51df-4dd0-bd2e-c63370de1a6d"
playlist = gazu.playlist.get_playlist(playlist_id)
entity_ids = [
    "5c902f4b-0f79-4a2a-920f-2c4a6e24f064",
    "51039784-7065-425f-b0aa-0a3df51db149",
    "948a16ad-f3ea-46a0-8e51-209bd0fd17b1",
    "158622b1-8c45-4eea-8d4a-6ed95da958e4",
    "bf6ce28f-21da-42d0-a052-3615e0e42e8f",
]

print(f"Test Playlist contains {len(playlist['shots'])} entities, trying to add {len(entity_ids)} for a total of {len(playlist['shots']) + len(entity_ids)}.")

now = datetime.now()
with ThreadPoolExecutor(max_workers=5) as executor:
    executor.map(add_to_playlist, entity_ids)

playlist = gazu.playlist.get_playlist(playlist_id)
print(f"Final Playlist re-queried contains {len(playlist['shots'])} entities.")


### Output ###

# Run1:
# Test Playlist contains 1 entities, trying to add 5 for a total of 6.
# Playlist updated, now has 2 entities.
# Playlist updated, now has 3 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Final Playlist re-queried contains 4 entities.

# Run2:
# Test Playlist contains 1 entities, trying to add 5 for a total of 6.
# Playlist updated, now has 2 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Final Playlist re-queried contains 5 entities.

# Run3: (5 entities present were different from previous runs)
# Test Playlist contains 1 entities, trying to add 5 for a total of 6.
# Playlist updated, now has 2 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Final Playlist re-queried contains 5 entities.

# Run4:
# Test Playlist contains 1 entities, trying to add 5 for a total of 6.
# Playlist updated, now has 2 entities.
# Playlist updated, now has 3 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Final Playlist re-queried contains 6 entities.

# Run5:
# Test Playlist contains 1 entities, trying to add 5 for a total of 6.
# Playlist updated, now has 2 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Playlist updated, now has 6 entities.
# Final Playlist re-queried contains 6 entities.

# Run6: (commented 2 of the entity id above - to avoid any possible caching)
# Test Playlist contains 1 entities, trying to add 3 more for a total of 4:
# Playlist updated, now has 2 entities.
# Playlist updated, now has 4 entities.
# Playlist updated, now has 4 entities.
# Final Playlist re-queried contains 3 entities.

# Run7:
# Test Playlist contains 1 entities, trying to add 3 more for a total of 4:
# Playlist updated, now has 2 entities.
# Playlist updated, now has 4 entities.
# Playlist updated, now has 4 entities.
# Final Playlist re-queried contains 4 entities.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions