2015-04-30 27 views
7

Używam Django, Selera i RabbitMQ. Co staram się osiągnąć, to upewnić się, że zadania związane z jednym użytkownikiem są wykonywane w kolejności (konkretnie, jeden w czasie, nie chcę współbieżności zadań na użytkownika).Jak zapewnić kolejność wykonywania zadań na użytkownika przy użyciu Celery, RabbitMQ i Django?

  • po dodaniu nowego zadania dla użytkownika powinno zależeć od ostatnio dodanego zadania. Dodatkowa funkcjonalność może obejmować brak dodawania zadania do kolejki, jeśli zadanie tego typu jest ustawione w kolejce dla tego użytkownika i jeszcze się nie uruchomiło.

Robiłem rozeznanie oraz:

  • nie mogłem znaleźć sposób, by połączyć nowo utworzone zadanie z jednej kolejce już w samej seler, łańcuchy wydają się być tylko w stanie połączyć nowe zadania .
  • Sądzę, że obie funkcje są możliwe do implementacji za pomocą niestandardowego programu obsługi wiadomości RabbitMQ, chociaż może być trudno kodować mimo wszystko.
  • Przeczytałem także o selekcji teryktów i może to być najłatwiejszy sposób zapewnienia kolejności wykonania, ale jak połączyć nowe zadanie z "applied_async" "task_tree" lub kolejką? Czy jest jakiś sposób, aby zaimplementować tę dodatkową, bez duplikatów funkcjonalność, korzystając z tego pakietu?

Edit: Jest to także ta „blokada” przykład w celery cookbook i jako koncepcja jest w porządku, nie widzę możliwy sposób, aby działać zgodnie z przeznaczeniem w moim przypadku - po prostu jeśli nie mogę pozyskać blokadę dla użytkownika, zadanie musiałoby zostać ponowione, ale oznacza to, że trzeba go przenieść na koniec kolejki.

Jaki byłby najlepszy sposób postępowania?

+0

Zakładam, że nie wiesz, jakie zadania dla danego użytkownika są przed wstawieniem zadania? –

+0

Dlaczego sam nie utworzyć kolejki (na użytkownika) i nie wykonywać zadań z Selera? – trinchet

Odpowiedz

0

Jeśli skonfigurujesz pracowników do selera, aby mogli wykonywać tylko jedno zadanie na raz (patrz ustawienie worker_concurrency), możesz wymusić współbieżność, której potrzebujesz dla każdego użytkownika. Aby uzyskać kolejkę zadań na podstawie identyfikatora użytkownika, za pomocą metody takiej jak ta, aby uzyskać kolejkę zadań na podstawie identyfikatora użytkownika, każde zadanie zostanie przypisane do tej samej kolejki dla każdego użytkownika. Pracownicy musieliby być skonfigurowani tak, aby wykorzystywać tylko zadania z pojedynczej kolejki zadań.

Byłoby rozegrać tak:

  1. użytkownika 49 uruchamia zadanie

  2. Zadanie jest wysyłane do user_queue_9

  3. Gdy jedyny pracownik seler, że słucha user_queue_9 jest gotowy do użycia nowego zadania, zadanie zostanie wykonane.

Jest to odpowiedź hacky chociaż, ponieważ

  • wymagające tylko jednego pracownika seler dla każdej kolejce jest system kruche - jeżeli pracownik przestaje seler, cała kolejka zatrzymuje

  • robotnicy są uruchomione nieefektywnie

+0

Bazując na tym, dlaczego nie używałbyś po prostu dziesięciu segmentów i mapowałbyś do kolejki z "user.id% 10" lub w przypadku łańcucha znaków "hash (user.id)% 10"? – knipknap

+0

Dzięki, uświadomiłeś sobie, że nie rozwiązałem części pytania dotyczącej współbieżności - moja odpowiedź nie jest jeszcze poprawna. –