-
-
Notifications
You must be signed in to change notification settings - Fork 36
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
Fix potential deadlock during migrations caused by Celery Beat #75
Conversation
Sorry for the delay, I will have a deeper look into this later on today. Currently, what I suggest is maybe dropping the filters from the settings and taking a more flexible approach via a method? So the class TenantAwareSchedulerMixin:
def filter_available_tenants(self, tenants: List[object]) -> List[object]:
return tenants
def apply_entry() -> ...:
...
tenants = get_tenant_model().objects.all()
tenants = self.filter_available_tenants(tenants)
... This would allow people to define their own semantics of "ready". Whether its stored in the model or somewhere else. This would also not be limited to ready tenants only, supporting other usecases. WDYT? |
I think it makes sense. This implementation was a quick attempt to generalise our use case, where I like your approach and I can update the PR based on your comments. I'd maybe suggest to name the whole thing TenantModel = get_tenant_model()
class TenantAwareSchedulerMixin:
def get_queryset(self) -> Iterable[TenantModel]:
"""Override this method to provide your own definition of `ready` tenants"""
return TenantModel.objects.all()
def apply_entry() -> None:
tenants = self.get_queryset()
... |
I thought of naming it in the likes of |
Looks great, will release this later today! Loving all your contributions - da true MVP! Your attention to the README and documentation is also stellar! |
Awesome! Thanks. Glad to contribute to this project 👍 |
Released in |
When using a subclass of
TenantAwareSchedulerMixin
, there's a risk that very frequent (or just unfortunately timed) celery tasks might cause a deadlock when running migrations for a new tenant. This is specially true for bigger projects with a lot of migrations and new tenants (in our setup, migrations can last more than 30mins).In order to mitigate this, we need a flag in the tenant model that indicates whether or not the tenant is ready for usage (at least for
beat
), but sincedjango-tenants
doesn't provide any, the user of the library must configure their projects to change the filtering behaviour of the scheduler based on their own implementation.The proposed solution adds a configurable filtering dictionary that's picked up by the scheduler and used to filter the queryset of tenants for which it will run migrations.
Adding new tenants then becomes a matter of creating them, running their migrations (either synchronously or asynchronously) and finally setting the flags to start counting them as
ready
. I.E: