2010-10-22 7 views
1

Je suis en train de créer une application Web de recherche qui exécute une analyse de lots longue pouvant durer plusieurs heures. J'utilise Grails mais je pense que c'est un problème de conception générale. Le traitement par lots peut être démarré par une URL, par ex.Exécution d'expériences longues à partir d'une interface Web

http://mydomain/experiment/run?a_lot_of_params

Et cette page renvoie les informations à propos de l'expérience (dont les données sont stockées dans la partie arrière et sont accessibles par une autre interface Web). par exemple. Le problème avec cette approche est: si l'expérience dure quelques minutes, il est bon de laisser une page web en attente. Mais que se passe-t-il si l'expérience dure 10 heures? Que faire si l'utilisateur ferme la page? Existe-t-il un modèle de conception correct à suivre pour ce type de situation?

Merci pour tous les conseils.

+0

Qu'avez-vous fini par faire? –

Répondre

2

Vous pouvez donner un jeton à l'utilisateur et lui demander d'entrer ce jeton pour afficher l'état du processus. À la fin du processus, vous pouvez informer l'utilisateur par e-mail/appel/SMS.

0

Le traitement par lots est-il asynchrone? Sinon, vous devrez le faire tourner dans un autre thread. Un exemple:

class BatchController { 

    def batchExecutionService // has the logic to run the batch operation 

    // this should probably only take POST requests, but that's left as a later exercise 
    def execute = { 

     def batchId 

     new Thread(new Runnable() { 
      batchExecutionService.executeBatch(batchId, params) 
     }).start() 

     render batchId // could also set response status to 202 Accepted 
    } 

    def check = { 
     render batchExecutionService.getStatus(params.batchId) 
    } 

    def retrieve = { 
     if(batchExecutionService.getStatus() != Status.FINISHED) { 
      // error response, could be 404 if report is not created yet, or something else 
     } 
     render batchExecutionService.getReport(params.batchId) 
    } 
} 

La mise en œuvre ci-dessus est assez brut, mais transmet le message général. Quelques notes sur elle:

  • Vous ne voudriez probablement pas tout nouveau un Thread et de l'utiliser, il y a de meilleures façons de le faire (mais donnerait un exemple plus complexe). Une solution possible serait le plugin BackgroundThread ou le plugin Quartz.
  • L'action execute ne devrait pas prendre les requêtes GET avec des paramètres de requête comme vous le faites actuellement. Mais c'est une discussion entièrement différente. Voir this pour référence.