La mia applicazione deve eseguire un'operazione ogni 10 minuti, ma quell'operazione viene attivata molte volte più frequentemente. Occasionalmente viene attivato tre o quattro volte al secondo in processi diversi, e questa è la cosa principale che voglio evitare.
È Django, e all'inizio ho usato la funzione django.core.cache
, ma sono ancora ottenere più di un lavoratore eseguendo l'operazione contemporaneamente.
Anch'io ho Redis, e so che WATCH e MULTI possono essere usati per prevenire le condizioni di gara, ma i django-redis la libreria non li supporta.
Questa è la mia soluzione; si prega di commentare quanto bene (o non) impedisce a più lavoratori (processi) di eseguire l'operazione contemporaneamente:
- Avere una tabella MySQL con campi
when
euuid
e solo una riga singola che inizia con entrambi i valori NULL. - Quando a un lavoratore viene detto di iniziare l'operazione, si chiude presto se
when
è inferiore a 10 minuti fa. - Altrimenti, genera un UUID e lo memorizza nella tabella, aggiornando
when
inNOW()
nella stessa query. - Quindi, seleziona la riga e chiudi presto se
uuid
non corrisponde a quello appena generato. - Altrimenti continua con l'operazione
Questo si basa su MySQL che impone l'ordine di letture e scritture e impone che solo una query acceda alla riga in una volta, il che potrebbe essere un assunzionamento non valido.
Qualsiasi altro modo per mantenere i processi di Celery dall'esecuzione simultanea di un'attività sarebbe altrettanto utile.