Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using cache to stash StateLog instances #77

Open
tysonclugg opened this issue Aug 30, 2018 · 2 comments
Open

Stop using cache to stash StateLog instances #77

tysonclugg opened this issue Aug 30, 2018 · 2 comments

Comments

@tysonclugg
Copy link

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.

@tysonclugg
Copy link
Author

This results in StateLog instances being lost if multiple concurrent requests change the state of a single object.

This part of the problem is actually quite common and can occur simply as a result of double-clicking a form submit button, which can occur for lots of different reasons. Of course solutions for preventing double submission exist, but there are other causes such as multiple users working on a single object simultaneously that should be handled as well.

@blueyed
Copy link
Contributor

blueyed commented Sep 5, 2018

Only skimmed it, but wouldn't using something along https://github.com/saxix/django-concurrency help here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants