Hi everyone,

on StackOverflow the question on how to overload the ManyRelatedManager
for ManyToMany relations has been asked multiple times, but none of the
answers seemed to be satisfying. So I would like to talk about it with you.

## My problem

The backend of my Django app gets triggered by events of a RabbitMQ
server. After pre-filtering the backend dispatches a Celery task to
process data from a remote system to which the event belongs.
Unfortunately events for the same object can arrive in bursts leading to
multiple Celery tasks processing the same objects almost simultaneously.

## My solution so far

In my custom ModelManager I explicitly use Postgres Advisory locks, e.g.
in `get_or_create`, which is working really well.

## Missing link

As my data model contains quite a few ManyToMany relations I would
prefer to define the usage of locks only once in the methods of a class
derived from ManyRelatedManager, e.g. in the `set` method.
So far I was unable to figure out how to do that. Any suggestions?

## Example

To give you a better understanding let's look at some code excerpts:

```
class ExtendedQuerySet(QuerySet):
    def get_or_create(self, defaults=None, _deadlocks=5, **kwargs):
        try:
            with advisory_lock(self.model.__name__):
                return super().get_or_create(defaults, **kwargs)
        except DeadlockDetected as error:
            # retry in a second...
            ...

class ExtendedManager(Manager.from_queryset(ExtendedQuerySet)):
    pass

class Reference(models.Model):
    # removed field definitions

    objects = ExtendedManager()

class Request(models.Model):
    # removed some field definitions
    references = models.ManyToManyField(Reference)

    objects = ExtendedManager()
```

If two Celery tasks try to call e.g.
`Reference.objects.get_o_create(...)` at the same time, the locks work
as expected. But e.g. calling `request.references.set(...)` can fail
(unique constraint violation) in the second Celery task due to a race
condition, that I would like to avoid using locks.


Thanks for your help.


Andreas

-- 
Andreas Hasenkopf
Phone:       +49 151 11728439
Homepage:    https://hasenkopf.xyz
GPG Pub Key: http://goo.gl/4mOsM

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/fa44eb44-4a05-7c86-cd72-22e03817e545%40hasenkopf2000.net.

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to