2010-04-30 13 views
10

Ultimamente sto giocando con altri framework, come NodeJS.Esecuzione di richieste non bloccanti? - Django

Mi piace la possibilità di restituire una risposta e di poter eseguire ulteriori operazioni.

ad es.

def view(request): 
    do_something() 
    return HttpResponse() 

    do_more_stuff() #not possible!!! 

Forse Django offre già un modo per eseguire le operazioni dopo il ritorno di una richiesta, se questo è il caso, che sarebbe grande.


L'aiuto sarebbe molto apprezzato! = D

risposta

10

non appena estratto dal metodo. È possibile utilizzare qualcosa come Celery che passerebbe l'attività do_more_stuff su una coda e quindi farlo eseguire do_more_stuff() al di fuori del flusso di richiesta/risposta http.

7

Django consente di eseguire questo con i segnali, ulteriori informazioni possono essere trovati here. (Si noti che, come ho detto nei commenti seguenti, i segnali non sono non bloccanti, ma consentono di eseguire codice dopo aver restituito una risposta in una vista.)

Se stai cercando di fare molti, molti richieste asincrone e richiedono che siano non bloccanti, si consiglia di controllare Tornado.

+0

Inoltre, questo metodo non sarà tecnicamente non bloccante come Django non è un quadro non bloccante nella maggior parte delle implementazioni, ma ti consente di fare qualcosa dopo il ritorno di una risposta. Tornado ti consente di eseguire richieste non bloccanti. – Zack

+0

@Zack: grazie per quello, non mi ero reso conto che i segnali mi avrebbero aiutato in questo. – RadiantHex

+0

Non dimenticare di contrassegnarlo come risposta, se funziona :) – Zack

2

Poiché si sta tornando dalla funzione, do_more_stuff non verrà mai chiamato.

Se stai guardando cose pesanti da fare in coda, prima di tornare come suggerisce Ross (+1 per Celery).

se tuttavia stai cercando di restituire del contenuto ... quindi fare qualcosa e restituire più contenuti allo streaming dell'utente è probabilmente quello che stai cercando. È possibile passare un iteratore o un generatore a HttpResponse, e itererà e distribuirà il contenuto in modo ridondante. Ci si sente un po 'schifo, ma se sei un generatore di rockstar potresti essere in grado di fare abbastanza nei vari stati per ottenere ciò che desideri.

O Credo che si potrebbe semplicemente ridisegnare la tua pagina di utilizzare un sacco di Ajax a fare ciò che è necessario, tra cui sparando eventi per Django di vista, la lettura dei dati dalle viste, ecc

E 'sorta di si riduce a dove si trova il peso di async: client, server o risposta.

Non ho ancora familiarità con node.js, ma sarebbe interessante vedere il caso d'uso di cui stai parlando.

EDIT: Ho fatto un po 'di più alla ricerca in segnali, e mentre lo fanno verificarsi nel processo, v'è una costruito nel segnale per request_finished dopo che la richiesta è stata gestita da Django, anche se è più di un ripostiglio che qualcosa specifica.

1

È possibile utilizzare il threading come correzione temporanea o come soluzione non di produzione, ma non è né scalabile né la migliore procedura. Usa il sedano per un design migliore!

def foo(request): 
    import threading 
    from time import sleep 
    def foo(): 
     sleep(5) 
     # Do something 
     print('hello, world') 
    threading.Thread(target=foo).start() 
    return JsonResponse(data={'detail': 'thread started'}) 
Problemi correlati