Domanda

ho scritto uno script python per elaborare alcuni dati da file CSV. Lo script prende tra i 3 ei 30 minuti per completare, a seconda delle dimensioni del CSV.

Ora voglio mettere in un'interfaccia web per questo, quindi posso caricare i file di dati CSV da qualsiasi luogo. Ho scritto una pagina di base di upload HTTP POST e usato modulo CGI Python - ma lo script appena scade dopo un certo tempo.

Lo script emette intestazioni HTTP alla partenza, ed emette bit di dati dopo l'iterazione di ogni riga del CSV. A titolo di esempio, questa istruzione di stampa farebbe scattare ogni 30 secondi o giù di lì.

# at the very top, with the 'import's
print "Content-type: text/html\n\n Processing ... <br />"

# the really long loop.
for currentRecord in csvRecords:
    count = count + 1
    print "On line " + str(count) + " <br />"

ho assunto il browser avrebbe ricevuto le intestazioni, e aspettare dal momento che continua a ricevere piccoli bit di dati. Ma quello che sembra realmente accadere è che non riceve alcun dato a tutti, ed i tempi Error 504 quando dato un CSV con un sacco di linee.

Forse c'è un po 'di caching accadendo da qualche parte? Dai tronchi,

[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm

Qual è il modo migliore per risolvere questo, o, non è forse opportuno eseguire tali script in un browser?

Modifica Questo è uno script per il mio uso - Io di solito intenzione di usarlo sul mio computer, ma ho pensato che un'interfaccia web-based potrebbe rivelarsi utile durante il viaggio, o per esempio da un telefono cellulare. Inoltre, non c'è davvero nulla da scaricare -. Lo script sarà molto probabilmente e-mail un report al termine

È stato utile?

Soluzione

Vorrei separare il lavoro in questo modo:

  1. Un URL web app che accettare il file CSV distaccati. L'applicazione web mette il contenuto CSV in una coda off line, per esempio una tabella di database. La risposta del web app dovrebbe essere un ID univoco per la voce in coda (utilizzare una colonna ID di auto-incrementato, per esempio). Il cliente deve conservare questo ID per parte 3.

  2. Un servizio di applicazione stand-alone che i sondaggi la coda per il lavoro, e fa il trattamento. Al termine del trattamento, memorizzare i risultati in un'altra tabella del database, utilizzando l'ID univoco come chiave.

  3. Un URL web app che possono ottenere risultati elaborati, http://server/getresults/uniqueid/. Se il trattamento è terminato (cioè l'ID univoco viene trovato nella tabella dei risultati del database), quindi restituire i risultati. Se non finito, la risposta dovrebbe essere un codice che indica questo. Per esempio un'intestazione HTTP personalizzato, una risposta di stato HTTP, il corpo di risposta 'IN ATTESA' o simili.

Altri suggerimenti

Ho avuto questa situazione prima e ho usato cronjobs. Lo script HTTP sarebbe solo scrivere in una coda di un posto di lavoro da eseguire (un DB o un file in una directory) e il cronjob avrebbe letto ed eseguire quel lavoro.

Avrete probabilmente bisogno di fare un stdout.flush(), come lo script non è realmente scrive ancora nulla al server web fino a quando hai scritto il valore di un buffer di pagina di dati -. Cosa che non accade prima del timeout

Ma il modo corretto per risolvere questo problema è, come altri hanno suggerito, per eseguire l'elaborazione in un thread / processo separato, e mostrare all'utente una pagina di auto-aggiornata che mostra lo stato, con una barra di avanzamento o qualche altra fantasia visiva per impedire loro di annoiarsi.

Guardando processi lunghi attraverso CGI . L'articolo utilizza Perl, ma la tecnica non dipende dalla lingua.

qui . Suggerisco di deposizione delle uova fuori dal processo lungo e la restituzione di un barra di avanzamento ajax based per l'utente. In questo modo essi utente ha il lusso di interfaccia web e si ha il lusso di non time-out.

imho il modo migliore sarebbe quello di eseguire uno script indipendente che aggiorna i messaggi da qualche parte (flat file, database, ecc ...). Non so come fork un processo indipendente in pitone, quindi non posso dare alcuna esempi di codice.

Per mostrare i progressi su un sito web implementare una richiesta AJAX ad una pagina che legge questi aggiornamenti di stato e, per esempio mostra una bella barra di avanzamento.

Aggiungi qualcosa come setTimeout ( "refreshProgressBar [...]) o meta-refresh per l'auto-aggiornamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top