2010-03-04 17 views
15

Sto cercando di capire come eseguire un processo in un thread in background in Django. Sono nuovo sia per Django che per i thread, quindi ti prego di sopportarmi se sto usando la terminologia sbagliata.Django: avvia un processo in un thread in background?

Ecco il codice che ho. Fondamentalmente vorrei iniziare start_processing non appena viene attivata la funzione success. Tuttavia start_processing è il tipo di funzione che potrebbe facilmente richiedere alcuni minuti o fallire (dipende da un servizio esterno su cui non ho alcun controllo), e non voglio che l'utente debba attendere che si completi con successo prima del la vista è resa. ('Successo' per quanto li riguarda, non dipende dal risultato di start_processing;. Sono l'unica persona che ha bisogno di preoccuparsi se non riesce)

def success(request, filepath): 
    start_processing(filepath) 
    return render_to_response('success.html', context_instance = RequestContext(request)) 

Dal Googling che ho fatto, la maggior parte delle persone suggerisce che i thread in background non sono usati in Django, e invece un job cron è più adatto. Ma vorrei che start_processing iniziasse non appena l'utente arriva alla funzione di successo, piuttosto che aspettare che il processo cron venga eseguito. C'è un modo per fare questo?

+1

Duplicato: http://stackoverflow.com/questions/844570/web-application-background-processes-newbie-design-question, tra molti altri. –

+1

Anche molti di questi sono utili: http://stackoverflow.com/search?q=%5Bdjango%5D+process –

+0

Dupliacte: http://stackoverflow.com/questions/1619397/how-to-start-a- long-running-process-from-django-view, http://stackoverflow.com/questions/219329/django-fastcgi-how-to-manage-a-long-running-process –

risposta

5

Non sono sicuro che sia necessario un thread per questo. Sembra che tu voglia solo generare un processo, quindi guarda nel modulo subprocess.

3

IIUC, Il problema qui è che il processo di server web potrebbe non piacere le discussioni in più di lunga durata, potrebbe uccidere/processi del server deporre le uova in quanto la domanda vanno su e giù, ecc ecc

Siete probabilmente meglio di comunicando a un processo di servizio esterno per questo tipo di elaborazione, invece di inserirlo nel processo wsgi/fastcgi del webserver.

Se l'unica cosa che si sta inviando è il filepath, dovrebbe essere piuttosto facile scrivere quell'app di servizio.

17

Se hai davvero bisogno di un trucco veloce, avvia semplicemente un processo usando subprocess.

Ma vorrei non consigliare creando un processo (o anche un filo), soprattutto se il vostro sito web è pubblico: in caso di carico elevato (che potrebbe essere "naturale" o il risultato di una banale DoS attacco) , genereresti molti processi o thread, che finirebbero per consumare tutte le risorse del tuo sistema e uccidere il tuo server.

Vorrei invece utilizzare un server di lavoro: io uso Celery (con come back-end), è molto semplice e funziona alla grande. Puoi controllare molti altri job server, come RabbitMQ o Gearman. Nel tuo caso, un job server potrebbe essere eccessivo: potresti semplicemente eseguire Redis e usarlo come un server di messaggi leggero. Ecco an example su come eseguire questa operazione.

Acclamazioni

7

in caso qualcuno vuole davvero correre un altro thread

def background_process(): 
    import time 
    print("process started") 
    time.sleep(100) 
    print("process finished") 

def index(request): 
    import threading 
    t = threading.Thread(target=background_process, args=(), kwargs={}) 
    t.setDaemon(True) 
    t.start() 
    return HttpResponse("main thread content") 

Ciò restituirà prima risposta, quindi stampare "processo finito" per consolare. Quindi l'utente non dovrà affrontare alcun ritardo.

L'utilizzo di Celery è sicuramente una soluzione migliore. Tuttavia, l'installazione di Celery potrebbe non essere necessaria per un progetto molto piccolo con un server limitato, ecc.

Potrebbe anche essere necessario utilizzare thread in un grande progetto. Perché eseguire Celery su tutti i tuoi server non è una buona idea.Quindi non ci sarà un modo per eseguire un processo separato in ogni server. Potresti aver bisogno di discussioni per gestire questo caso. Le operazioni del file system potrebbero essere un esempio. Tuttavia non è molto probabile ed è ancora meglio utilizzare Celery con processi a esecuzione prolungata.

Usare saggiamente.

Problemi correlati