Ho scoperto che è possibile impostare l'attività in modo che venga eseguita a intervalli specifici a orari specifici da here, ma ciò è stato eseguito solo durante la dichiarazione dell'attività. Come posso impostare un'attività da eseguire periodicamente in modo dinamico?sedan django: come impostare l'attività da eseguire a intervalli specifici programmaticamente
risposta
Il programma è derived from a setting e, pertanto, sembra essere immutabile in fase di esecuzione.
Probabilmente è possibile ottenere ciò che si sta cercando utilizzando Task ETAs. Ciò garantisce che l'attività non verrà eseguita prima del l'ora desiderata, ma non promette di eseguire l'attività all'orario designato, se i lavoratori sono sovraccaricati all'ETA designato, l'attività può essere eseguita in un secondo momento.
Se tale restrizione non è un problema, si potrebbe scrivere un compito che prima si correre come:
@task
def mytask():
keep_running = # Boolean, should the task keep running?
if keep_running:
run_again = # calculate when to run again
mytask.apply_async(eta=run_again)
# ... do the stuff you came here to do ...
Il principale svantaggio di questo approccio è che si fa affidamento sulla taskstore di ricordare i compiti in volo. Se uno di questi fallisce prima di sparare a quello successivo, l'attività non verrà mai più eseguita. Se il tuo broker non è persistente su disco e muore (prendendo tutte le attività in volo con esso), quindi nessuna di quelle attività verrà eseguita di nuovo.
È possibile risolvere questi problemi con una sorta di registrazione delle transazioni e un'attività periodica di "bambinaia" il cui compito è quello di trovare attività ripetitive che siano morte inopportune e farle rivivere.
Se dovessi implementare quello che hai descritto, penso che questo sarebbe il modo in cui mi avvicinerei.
Vedi qui http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html
penso che non si può fare in modo dinamico ... modo migliore è creare un'attività in un'attività: D
per esempio, si desidera eseguire qualcosa per X sec tardi quindi si crea nuova task con x sec di ritardo e in questa attività creare un'altra attività per il ritardo N * X sec ...
celery.task.base.PeriodicTask
definisce is_due
che determina quando deve essere la prossima corsa. È possibile sovrascrivere questa funzione per contenere la logica di esecuzione dinamica personalizzata. Vedere la documentazione qui: http://docs.celeryproject.org/en/latest/reference/celery.task.base.html?highlight=is_due#celery.task.base.PeriodicTask.is_due
Un esempio:
import random
from celery.task import PeriodicTask
class MyTask(PeriodicTask):
def run(self, **kwargs):
logger = self.get_logger(**kwargs)
logger.info("Running my task")
def is_due(self, last_run_at):
# Add your logic for when to run. Mine is random
if random.random() < 0.5:
# Run now and ask again in a minute
return (True, 60)
else:
# Don't run now but run in 10 secs
return (True, 10)
puoi darmi un esempio di come eseguire l'override durante il runtime? Suppongo di non poter usare .delay poiché non esiste run() per le classi periodicTask – goh
Si definisce la propria classe di pianificazione (celery.schedules.schedule) con un metodo personalizzato is_due. 'CELERYBEAT_SCHEDULE = {" my name ": {" task ":" myapp.mytask ", schedule": myschedule()}} ' – asksol
Questo dovrebbe aiutare a qualche ... http://celery.readthedocs.org/en/latest/faq.html#can-i-change-the-interval-of-a-periodic-task-at-runtime
Dopo aver definito una pianificazione personalizzata, assegnarlo al proprio compito come asksol ha suggerito sopra.
CELERYBEAT_SCHEDULE = {
"my_name": {
"task": "myapp.tasks.task",
"schedule": myschedule(),
}
}
si potrebbe anche voler modificare CELERYBEAT_MAX_LOOP_INTERVAL se si desidera che il vostro programma per aggiornare più spesso che ogni cinque minuti.
Sì, lo scheduler non è ottimizzato per le pianificazioni dinamiche, ma è possibile implementare il proprio 'Schedule' con un metodo' is_due' come descritto sopra, anche avere l'attività riprogrammarsi è un'opzione che molti usano, ma poi è necessario assicurati che il primo compito sia sempre attivato, il che non è così facile. Un'altra opzione è quella di usare DatabaseScheduler in django-celery, questo supporta programmi dinamici e può anche essere usato al di fuori dei progetti Django. Inoltre, creare i propri programmi di pianificazione non è così difficile. – asksol
@asksol, le documentazioni per django-sedano sono vuote.dove posso trovare informazioni su come utilizzare il database di pianificazione? – goh
@amateur Bene, la documentazione è davvero scarsa qui: – asksol