2009-06-10 9 views
0

Je cours plusieurs tâches idempotentes pour rassembler un lot de données. J'ai découvert que plusieurs fois le calcul est retardé de manière significative en raison de quelques tâches sur cent.Accélération de tâches idempotentes irrégulières

Ce que j'aimerais, c'est une façon de regarder ces tâches et de lancer à nouveau les retardataires s'ils sont considérablement retardés.

Existe-t-il une bibliothèque standard ou un idiome pour cela en Java? J'utilise actuellement la paire ExecutorService/ExecutorCompletionService pour faire le travail.

Répondre

2

Si vous avez accès à l'objet Future représentant cette tâche, vous pouvez vérifier isDone() et cancel() si nécessaire. Vous devrez interroger ces objets futurs et resoumettre en conséquence. Cela dépend également de votre sous-jacente Runnables traitant les exceptions InterruptExceptions de manière appropriée.

1

Vous pouvez créer un type de gestionnaire de tâches contenant une référence à chacune des tâches. Ce gestionnaire de tâches peut être responsable du lancement de chaque tâche et de la gestion de ExecutorService. La première et dernière opération de chaque tâche consiste à enregistrer avec le gestionnaire le début et la fin de la tâche. Le gestionnaire peut alors construire une image statistique qui est une moyenne du temps nécessaire pour effectuer chaque tâche. Le gestionnaire de tâches parcourt périodiquement sa liste de tâches en cours d'exécution à la recherche de «valeurs aberrantes» qui sont toujours en cours d'exécution et qui ont considérablement dérivé du temps moyen pris pour une tâche particulière. Il peut ensuite annuler ces tâches et les redémarrer.

Voici une esquisse très approximative de ce que vous pourriez faire ...

public class Task implements Runnable { 
    protected TaskManager manager_ = null; 
    protected String taskClass_ = null; 
    protected String taskId_ = null; 

    protected Task(TaskManager manager, String taskClass) { 
     manager_ = manager; 
     taskClass_ = taskClass; 
    } 

    /* 
     * Override this and perform specific task. 
     */ 
    protected void perform() { } 

    public void run() { 
     try { 
      manager_.taskStarted(this); 
      perform(); 
      manager_.taskCompleted(this); 
     catch(InterruptedException) { 
      manager_.taskAborted(this); 
     } 
     finally { 
     } 
    } 
} 


public class TaskManager { 
    ExecutorService service_ = null; 

    public TaskManager() { 
     service_ = new ExecutorService(); 
     // start the monitoring thread. 
     service_.execute(this); 
    } 

    public void runTask(Task t) { 
     service_.execute(t); 
    } 

    public void taskStarted(Task t) { 

     1. Note the time that this task (with unique id) has started. 
     2. Add time to a hash map. 
     3. Add task to list of executing tasks. 
    } 

    public void taskComplete(Task t) { 
     1. Find the task id in hash map 
     2. note how long it took to execute. 
     3. modify statistics of how long the task took against 
      the task Class Id. 
     4. Remove task from list of executing tasks. 
    } 

    public void taskAborted(Task t) { 
     // just remove the task from list of running tasks 
     // without altering the statistics. 
    } 
    public void run() { 
     1. Go though the list of executing tasks looking for 
      tasks whose current time - start time is outside the 
      time statistics for the task class id. 
     2. cancel the task and start again. 
    } 
} 
Questions connexes