Programmazione Web, modalità standard per gestire una risposta che richiede tempo per essere completata

3

Con l'invio normale del modulo, utilizzo il pattern Post / Redirect / Get, durante l'elaborazione dei moduli.

Ho un'applicazione di database creata con Django. Voglio consentire agli utenti di selezionare un numero di elementi dal database, quindi avviare un'attività computazionalmente intensiva basata su tali elementi.

Mi aspetto che l'operazione duri tra 10 minuti e 2 ore per essere completata.

Esiste un approccio standard per gestire richieste come questa (ad esempio, che non vengono restituite immediatamente)? Idealmente ci sarebbe un modo per mostrare i progressi.

    
posta wobbily_col 16.10.2013 - 12:16
fonte

5 risposte

5

Vorrei attivare un lavoro (ad esempio un thread di lavoro) per questo che è in grado di segnalare lo stato di avanzamento e terminare la richiesta corrente. E per visualizzare il processo, vorrei sondare i progressi di questo lavoro via Ajax o simili.

    
risposta data 16.10.2013 - 12:26
fonte
5

Celery è una configurazione per django progettata appositamente per questo tipo di situazione. È possibile avviare un'attività in background e lasciarla eseguire in modo asincrono come thread di lavoro.

Qualcuno ha anche creato una barra di caricamento AJAX per mostrare lo stato di avanzamento del lavoro.

    
risposta data 16.10.2013 - 13:30
fonte
2

Il thread effettivo che esegue il lavoro deve essere separato dalla sua associazione con la sessione (sebbene sia possibile collegarlo all'utente che esegue il lavoro). Avere una classe con ambito applicativo (chiamiamola JobQuery) che riceve richieste di lavoro e risponde a domande sui lavori correnti.

La tua applicazione web diventa quindi nuovamente apolide. Ogni volta che si desidera conoscere lo stato di un lavoro, l'applicazione Web esegue una richiesta utilizzando JobQuery.

In caso di errore, un componente del database è utile. Se il server Web si arresta in modo anomalo o si verificano altri problemi imprevisti, JobQuery, oltre a avviare i lavori, deve anche conservare le schede scrivendo lo stato nel database. Se qualcosa dovesse accadere, JobQuery può indicare lo stato di errore dei lavori incompleti o persino riprendere da dove era stato interrotto.

Ciò che è importante qui è che il lato dell'ambito della sessione della tua applicazione web è libero di continuare a rispondere all'utente e continua ad essere apolide, garantendo nel contempo che non si perdano lavori di 2 ore nel vuoto in caso di problemi.

    
risposta data 16.10.2013 - 12:41
fonte
2

HTTP 202 accettato

The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request [...] 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.

Il Web è orientato alle risorse, quindi il "puntatore a un monitor di stato" sarebbe un URI di una risorsa che hai reso disponibile. In un certo senso, potresti avere una tabella di database di lavori con informazioni sullo stato associate che il cliente può ottenere. Le altre risposte contengono informazioni utili su come implementare i lavori, ma ritengo che la tua domanda riguardi il web - e la risposta è sì, HTTP ha codici di stato ragionevolmente ben pensati per trasmettere questo tipo di informazioni.

    
risposta data 17.10.2013 - 03:27
fonte
0

Probabilmente vorresti una sorta di coda di lavoro qui. La forma esatta di una tale coda può variare. Ma in pratica lo script sul lato server aggiungerà un'attività in una coda. Le attività in coda vengono gestite da un processo completamente diverso e contrassegnate come completate al termine. Puoi quindi utilizzare qualcosa come websocket o polling lungo per "guardare" la coda e riportare lo stato dell'attività.

Ad esempio, potresti creare una tabella di database che funzionerà come una coda. Quando una richiesta arriva al tuo server, inserisci le informazioni necessarie sull'attività in quella tabella. Un processo separato eseguirà il polling di tale tabella ogni X secondi / minuti e, quando trova una nuova voce, esegue il lavoro richiesto. Al termine del lavoro, contrassegna l'attività come completa nel database. Nel frattempo , all'interno del browser, hai aperto una connessione al tuo server utilizzando sia websocket che polling lungo. Questo eseguirà il polling della coda per lo stato dell'attività e lo rimanderà all'utente finale che potrà quindi vedere qual è lo stato dell'attività.

Questa è una semplice soluzione basata su tabelle. Esistono naturalmente altri modi per gestire le specifiche (code dei messaggi).

    
risposta data 17.10.2013 - 06:26
fonte

Leggi altre domande sui tag