Skip to content

Stop using cache to stash StateLog instances #77

@tysonclugg

Description

@tysonclugg

When using DJANGO_FSM_LOG_STORAGE_METHOD = 'django_fsm_log.backends.CachedBackend', a cache is used to stash unsaved log instances created during the pre transition callback. These unsaved StateLog instances are then retrieved and saved as part of the post transition callback.

Problems arise when DJANGO_FSM_LOG_CACHE_BACKEND points to a shared cache, since the PendingStateLogManager._get_cache_key_for_object method doesn't differentiate cache keys between between different requests. This results in StateLog instances being lost if multiple concurrent requests change the state of a single object. This could be solved by either including request identifying details in the cache key, or by using a specialised cache backend (such as django-request-cache). Better yet, the StateLog instance should be stashed on the related object itself.

Easy enough to fix, however...

I've seen code that relies on current cache semantics. More specifically, I have code that approximates the behaviour of queryset.select_for_update() to ensure pending StateLog instances are written to the DB before proceeding:

# wait for pending StateLog instances to be written to the DB before querying
# to find the most recent instances
while(StateLog.pending_objects.get_for_object(instance) is not None):
    sleep(0.05)

Changing current cache semantics would break code like this. This wouldn't be so bad except that it seems to be supported behaviour.

I'm not sure how to proceed, any help would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions