2013-08-05 10 views
6

Sono nuovo di Play Come ho capito, potrebbe essere sbagliato, play framework non è bloccante gestendo le richieste in modo asincrono, le lunghe operazioni di blocco dovrebbero essere eseguite in modo asincrono usando le promesse. Quindi, quando dovrei usare promesse o promesse mappate per gestire una determinata richiesta e quando no?In Play framework, quando utilizzare Promises per gestire una richiesta e quando no?

Ad esempio, supponiamo che un utente carichi un file, quando arriva al controller, sposto il file dalla cartella temporanea alla cartella desiderata e inserisco un record del database. Quindi questo comporta 2 operazioni di blocco, il file si sposta e si inserisce nel database. Supponiamo che il file non sia grande, diciamo 10MB max, quindi il movimento del file dovrebbe essere rapidamente risonabile. E l'inserimento di un record db dovrebbe essere veloce anche con un driver di database di blocco.

In questo semplice caso, dovrei utilizzare una promessa/futuro per eseguire le 2 operazioni o 2 promesse mappate (spostare il file quindi inserire record db) o non utilizzare la promessa? E perché?

Si prega di condividere i tuoi pensieri/esperienze. Grazie in anticipo.

risposta

4

In realtà è una linea sottile, e decidere cosa succede in un futuro e ciò che non finisce per essere piuttosto dipendente dall'applicazione.

In generale, non è necessario preoccuparsi di inserire le chiamate al database in un futuro. Poiché il driver sottostante sta bloccando, il tuo sarà bloccato da qualche parte, anche se lo metti in un futuro o un attore. Quindi: prova a ridurre la latenza db. Assicurati che il tuo database sia vicino (rete topologicamente parlando) e abbia risorse sufficienti.

Lo spostamento del file in modo non bloccante può essere abbastanza banalmente trattati con qualcosa di simile:

def uploadFile() = Action { 
    Async { 
    // handle file moving 
    Ok 
    } 
} 

Diciamo, però, avete ancora due cose costose da fare con il file. Se un'azione dipende dall'altra, puoi organizzarla come preferisci (in un futuro va benissimo). Devi finire il primo compito prima di iniziare il secondo. Il codice potrebbe essere più pulito, tuttavia, utilizzando due future. Alto livello, qualcosa di simile:

for { movedFile <- moveFile(file) 
    analyzedFile <- analyzeFile(movedFile) } yield analyzedFile 

sembra pulito per me. Ma non pensare di dover dividere ogni piccola azione nel proprio futuro.

Tuttavia, se si dispone di due attività che possono essere eseguite in modo indipendente, è possibile utilizzare due future contemporaneamente per eseguire entrambe le operazioni contemporaneamente.

+0

Grazie Andrew per la spiegazione chiara, questo ha molto senso per me. – Kevin

Problemi correlati