2012-02-29 9 views
6

Sto sviluppando un server web django su cui un'altra macchina (con un IP noto) può caricare un foglio di calcolo sul mio server web. Dopo il il foglio di calcolo è stato aggiornato, voglio attivare qualche elaborazione/convalida/analisi sul foglio di calcolo (che può richiedere> 5 minuti --- troppo a lungo perché l'altro server possa ragionevolmente attendere una risposta) e poi inviare l'altro macchina (con un IP noto) a HttpResponse che indica che l'elaborazione dei dati è terminata.dopo il ritorno di HttpResponse dalla vista django

mi rendo conto che non si può fare processing.data() dopo il ritorno di un HttpResponse, ma funzionalmente voglio codice che assomigli a questo:

# processing.py 
def spreadsheet(*args, **kwargs): 
    print "[robot voice] processing spreadsheet........." 
    views.finished_processing_spreadsheet() 

# views.py 
def upload_spreadsheet(request): 
    print "save the spreadsheet somewhere" 
    return HttpResponse("started processing spreadsheet") 
    processing.data() 

def finished_processing_spreadsheet(): 
    print "send good news to other server (with known IP)" 

so come scrivere ogni funzione individualmente, ma come faccio in modo efficace chiama processing.data()dopoviews.upload_spreadsheet ha restituito una risposta?

Ho provato a utilizzare django's request_finished signaling framework ma questo non attiva il metodo processing.spreadsheet() dopo aver restituito il HttpResponse. Ho provato ad utilizzare un decoratore su views.upload_spreadsheet con lo stesso problema.

Ho il sospetto che questo potrebbe avere qualcosa a che fare con la scrittura middleware o forse uno custom class-based view, nessuno dei quali ho alcuna esperienza con così ho pensato di porre la domanda all'universo in cerca di qualche aiuto.

Grazie per il vostro aiuto!

risposta

4

In effetti Django ha un modello sincrono. Se si desidera eseguire un'elaborazione asincrona reale, è necessaria una coda di messaggi. Il più usato con django è il sedano, può sembrare un po '"eccessivo" ma è una buona risposta.

Perché ne abbiamo bisogno? perché in un'app wsgi, apache fornisce la richiesta all'eseguibile e, l'eseguibile restituisce il testo. È solo una volta che l'eseguibile termina la sua esecuzione che apache riconosce la fine della richiesta.

+0

Grazie per aver spiegato perché è necessario, Cristophe. Basandomi sulle tue e sulla spiegazione di jpic, penso che controllerò il sedano dopo aver dormito un po 'di più. – dino

3

Il problema con la vostra implementazione è che se il numero di fogli di calcolo in corso è uguale al numero di lavoratori: il vostro sito Web non risponderà più.

è necessario utilizzare un sfondo coda compito, in fondo hanno 2 processi: il server e uno sfondo task manager. Il server deve delegare l'elaborazione del foglio di calcolo al task manager in background. Quando l'attività in background è terminata, dovrebbe informare il server in qualche modo. Ad esempio, può fare model_with_spreadsheet.processed = datetime.datetime.now().

Si dovrebbe usare uno sfondo Job Manager come django-ztask (molto facile setup), celery (molto potente, probabilmente eccessivo nel tuo caso) o anche uwsgi spooler (che richiede, ovviamente, l'implementazione uwsgi).

+0

Grazie per la risposta rapida. Basandomi sulle risposte di tua e di christophe31, penso che controllerò il sedano dopo aver dormito un po 'di più. – dino

+0

chiudi la domanda per favore – jpic