2013-08-06 15 views
16

Per una sola richiesta, è necessario eseguire una funzione dopo aver inviato la risposta al client. Poiché la funzione richiede tempo e che finisce nel timeout di connessione Socket error: [Errno 32] Broken pipeÈ necessario eseguire una funzione dopo aver restituito la risposta in Flask

C'è un modo in Flask per eseguire la funzione dopo il ritorno della richiesta

+3

Che cosa, esattamente, vuoi la funzione di fare dopo la richiesta finisce? Se si scrive su un log, questa è una cosa, ma se si desidera restituire i dati all'utente, non c'è modo di farlo se la connessione è effettivamente scaduta. Questa non è una cosa Flask, questa è solo una cosa HTTP; il browser, il web server o qualsiasi altra via di mezzo può chiudere la connessione. Se la tua richiesta impiega troppo tempo, considera di eseguirla in un processo separato, con la prima richiesta kicking off e la tua app automaticamente (o manualmente dall'utente) controllando periodicamente lo stato dell'attività tramite altre richieste. –

risposta

6

È possibile utilizzare il decoratore after_request o personalizzare per creare un after_this_request cui solo funziona per quella particolare richiesta.

Date un'occhiata a questo frammento http://flask.pocoo.org/snippets/53/

+7

Grazie per aver risposto rapidamente! after_this_request attende anche la funzione definita per essere completata e quindi restituisce la risposta c'è un modo per inviare prima la risposta e quindi eseguire la funzione – naga4ce

+1

c'è un modo per impostare il timeout della connessione di richiesta o il timeout della connessione di risposta nel pallone? – naga4ce

8

Si può provare l'uso di streaming. Vedere esempio successivo:

import time 
from flask import Flask, Response 

app = Flask(__name__) 

@app.route('/') 
def main(): 
    return '''<div>start</div> 
    <script> 
     var xhr = new XMLHttpRequest(); 
     xhr.open('GET', '/test', true); 
     xhr.onreadystatechange = function(e) { 
      var div = document.createElement('div'); 
      div.innerHTML = '' + this.readyState + ':' + this.responseText; 
      document.body.appendChild(div); 
     }; 
     xhr.send(); 
    </script> 
    ''' 

@app.route('/test') 
def test(): 
    def generate(): 
     app.logger.info('request started') 
     for i in range(5): 
      time.sleep(1) 
      yield str(i) 
     app.logger.info('request finished') 
     yield '' 
    return Response(generate(), mimetype='text/plain') 

if __name__ == '__main__': 
    app.run('0.0.0.0', 8080, True) 

Tutta la magia in questo esempio in genarator dove si può iniziare a dati di risposta, dopo fare un po 'personale e cedere i dati vuoti per terminare il vostro flusso.

Per le dita guardare http://flask.pocoo.org/docs/patterns/streaming/.

Problemi correlati