2013-01-04 12 views
5

Sto scrivendo il codice per partecipare a un servizio. Ricevo richieste POST a un particolare servizio e avvio l'elaborazione. L'intero processo è piuttosto semplice; I loop attraverso gli elementi nella richiesta e aggiungere ogni elemento al database. Il problema sorgere quando devo elaborare un sacco di oggetti e il ciclo prende come tre minuti per finire, poi, quando provo a rispondere:Errore con il servizio REST che richiede tempo in Python

status = '200 OK' 
headers = [('Content-type', 'application/json'),('Access-Control-Allow-Origin','*')] 
start_response(status, headers) 

return json.dumps(response) 

ottengo questo errore:

Exception happened during processing of request from ('XXX.XXX.XXX.XXX', 49172) 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock 
    self.process_request(request, client_address) 
    File "/usr/local/lib/python2.7/SocketServer.py", line 310, in process_request 
    self.finish_request(request, client_address) 
    File "/usr/local/lib/python2.7/SocketServer.py", line 323, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
    File "/usr/local/lib/python2.7/SocketServer.py", line 640, in __init__ 
    self.finish() 
    File "/usr/local/lib/python2.7/SocketServer.py", line 693, in finish 
    self.wfile.flush() 
    File "/usr/local/lib/python2.7/socket.py", line 303, in flush 
    self._sock.sendall(view[write_offset:write_offset+buffer_size]) 
error: [Errno 32] Broken pipe 

I don so se questo aiuta, ma la richiesta POST è un POST inoltrato fatto da un browser a un dominio diverso (ecco perché un Access-Control-Allow-Origin) e tutti gli accessi al database sono fatti usando un singolo oggetto che interagisce con il database utilizzando SQLAlchemy (può essere visto come un modello Java EEDAO).

Come evitare questo errore?

+0

possibile duplicato del [errore tubo di Django server di sviluppo rotto] (http://stackoverflow.com/questions/10253288/django-development-server-broken -pipe-error) – miku

+0

Puoi renderlo asincrono. Non appena tutti i dati sono qui, si invia un token che dice che i dati vengono ricevuti e sul lato client è possibile visualizzare un messaggio "Caricamento in corso ...". Fai in modo che il client verifichi periodicamente gli aggiornamenti se i dati hanno terminato il caricamento e, una volta terminato, visualizzi l'ack completo. –

+0

Di solito quando ottengo un errore di pipe rotto, è qualcosa di stupido, come se il client fosse scaduto mentre stavo eseguendo il debug del codice del server. Se il processo richiede più di tre minuti, il processo dovrebbe essere eseguito in modo asincrono e si dovrebbe rispondere confermando che il processo è stato avviato correttamente anziché attendere fino a quando il processo non è stato eseguito per rispondere. –

risposta

5

Forse stai violando l'idea alla base di REST.

Se il processo potrebbe richiedere del tempo, il servizio potrebbe voler rispondere con una risposta 202 Accepted! Per una panoramica completa dei codici di risposta HTTP segui questo link: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

202 Accepted

The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.

The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.

+0

Forse hai ragione, un 202 suona come una buona idea, ancora come posso rispondere con un 202 e avviare l'elaborazione della richiesta allo stesso tempo? –

+0

in genere si avvia una discussione. Al suo completamento dovrebbe creare una risorsa, a cui si può accedere per ottenere richieste. – sschrass

+0

In questo caso, l'avvio di un processo asincrono è ciò che si desidera, se la richiesta richiede molto tempo per rispondere. Il codice 202 sembra la soluzione migliore. Quindi, avvia il processo, quindi restituisce 202 e continua l'elaborazione in background. –

2

Potrei sbagliarmi, ma mi sembra che la presa sia scaduta. Non lasciare il client sospeso per una risposta per più di tre minuti.

Invece, è necessario convalidare i dati e inviare un messaggio che informa che è stato ricevuto. Se necessario, puoi usare qualcosa come AJAX per dire al cliente che i dati sono stati inseriti dopo che è stato ricevuto.

+0

In realtà hai ragione, il problema è come rispondere in tempo (o 202 come SatelliteSD ha risposto) ed elaborare la richiesta. –

Problemi correlati