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
Invalidation of data stored in a primary/replica configured DB invalidates only for primary instance #37
Comments
We have recently commented the same behaviour here: #27 (comment) |
Thank you @marccerrato, didn't see that issue since it is closed. This is blocking for me since I am about to deploy a high traffic app, and I am stucked with only one DB of the two available. Regarding your post, as far as I can tell routers does not have to implement a method that returns the list of read DB aliases, so I don't think this is a viable solution, without the need to modify existing routers adding non-standard methods. I may be wrong since I'm not that experienced with Django, and I had no time to dig deeper. |
Then the only feasible options I see would be either to invalidate the table for all the available DB aliases or simply stop using the DB alias for generating the cache key. But let's wait for @BertrandBordage thoughts... 😄 |
Probably the best way is to stop using DB aliases, I see that DB routers are mainly used for two purposes:
In both cases table name, which contains the name of the app, seems to be a valid key since you can't have two apps with the same name in a single Django project, or two tables with the same name in one app as far as I know. Maybe I am missing something :) |
Short answer: you can’t use a replica DB with django-cachalot, and I will add it to the docs. Long answer: @micku: |
Thank you @BertrandBordage for your response. |
@BertrandBordage the other option was to invalidate the table for all the available database aliases. Would it make sense to you? |
@marccerrato: Yes, you’re right, but it can’t be done automatically, you have to do it yourself, and that’s what I’ll add to the docs. @micku, @marccerrato, could you therefore test if this works correctly? from cachalot.api import invalidate
from cachalot.signal post_invalidation
@receiver(post_invalidation)
def invalidate_replica(sender, **kwargs):
if kwargs['db_alias'] == 'default':
invalidate(sender, db_alias='replica') @micku Other similar django libraries will have the same problem if I remember correctly how they work. |
@BertrandBordage I'll be very happy to test this for you as soon as I can! |
@BertrandBordage The solution works :) Thanks! from cachalot.api import invalidate
from cachalot.signals import post_invalidation
from django.dispatch import receiver
@receiver(post_invalidation)
def invalidate_replica(sender, **kwargs):
if kwargs['db_alias'] == 'default':
invalidate(sender, db_alias='replica1') @micku Exactly for your case. |
@xino12 Cool :) Glad it works as expected! Yes, I forgot an import, that’s right. |
Thank you @xino12, I'm implementing it on our stage environment right now! |
Works really well! Just a note, I had to run |
Fixed by 286e590. |
I have a Django app with two MariaDB databases configured as primary/replica with the following configuration:
The router is configured to write on primary and read on replica:
When Django writes on a table, cache gets invalidated only on primary.
You can test this by configuring the router to randomly return the primary or the replica, you will see old and new value alternated refreshing the page.
Calling
./manage.py invalidate_cachalot
works, I think because it invalidates all the cache ignoring the database instance.The text was updated successfully, but these errors were encountered: