2012-08-17 8 views
14

Ho un compito, un po 'come questo:Sedano pianificazione dell'attività (Garantire un compito viene eseguito solo uno alla volta)

@task() 
def async_work(info): 
    ... 

In qualsiasi momento, posso chiamare async_work con alcune informazioni. Per qualche ragione, ho bisogno di assicurarmi che sia attivo un solo async_work alla volta, altra richiesta di chiamata deve attendere.

Così vengo con il seguente codice:

is_locked = False  
@task() 
    def async_work(info): 
     while is_locked: 
      pass 
     is_locked = True 
     ... 
     is_locked = False 

Ma dice che è valido per accedere alle variabili locali ... come risolverlo?

+0

Puoi pubblicare un messaggio di errore esatto? –

risposta

21

Non è possibile accedere alle variabili locali poiché è possibile avere diversi operatori di sedici che eseguono attività. E quei lavoratori potrebbero anche essere su host diversi. Quindi, in pratica, vi sono altrettante istanze variabili is_locked quanti sono i dipendenti di Celery che eseguono l'attività l'attività async_work. Pertanto, anche se il tuo codice non solleverà alcun errore, con esso non otterresti l'effetto desiderato.

Per raggiungere l'obiettivo è necessario configurare Celery per eseguire un solo operatore. Poiché ogni lavoratore può elaborare una singola attività in un dato momento, ottieni ciò di cui hai bisogno.

EDIT:

Secondo Workers Guide > Concurrency:

Per multiprocessing impostazione predefinita viene utilizzata per eseguire l'esecuzione simultanea di compiti, ma si può anche utilizzare Eventlet. Il numero di processi/thread worker può essere modificato utilizzando l'argomento e il numero di CPU disponibili sulla macchina.

Quindi è necessario eseguire il lavoratore in questo modo:

$ celery worker --concurrency=1 

EDIT 2:

Sorprendentemente non c'è un'altra soluzione, inoltre è anche nei documenti ufficiali, vedere l'articolo Ensuring a task is only executed one at a time .

+0

Puoi spiegarlo in modo più esplicito? Come configurare Celery per eseguire un solo worker? –

+0

"$ celery worker --concurrency = 1" Ha funzionato bene! Grazie davvero. –

Problemi correlati