2010-07-31 5 views
4

Я пытаюсь получить процент прогресса от асинхронного процесса EJB. Это возможно?Есть ли способ узнать о ходе асинхронного процесса EJB?

Есть ли у кого-нибудь идеи, как я мог это сделать?

+0

Вы должны проверить ход выполнения Послания, так может, что быть достигнуто путем мониторинга очередей? – zengr

+1

Возможный дубликат [Expose current progress of @Asynchronous function to view in View] (http://stackoverflow.com/questions/3355336/expose-current-progress-of-an-asynchronous-function-to-use-in -view) –

ответ

2

Для получения информации о ходе асинхронных процессов всегда сложно, особенно если вы не знаете, действительно ли они начались.

Лучший способ, который я нашел, - написать другую функцию, которая только что получит прогресс, поэтому, если у вас есть уникальный идентификатор для каждого вызова, то обновите hashmap с текущим процессом. Вы можете посмотреть на Concurrent Hashmap (http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html)

Тогда эта другая функция поиска просто примет уникальный идентификатор и вернет ход обратно клиенту.

Если он не был запущен, вы также можете вернуть его, и в идеале вы также захотите вернуть любые сообщения об ошибках, возникшие при обработке.

Затем, когда оно закончено, и вы вернули сообщение об ошибке или успех, затем удалите его из хэш-карты, клиент получил информацию, и эта информация не изменится, поэтому не стоит ее хранить.

UPDATE:

В интерфейсе сделать новую функцию

String progressDone(String id); 

Вы тогда смотрите, что синхронно, так как она просто выходит и приходит обратно, так что он может посмотреть вверх id в hashmap и вернуть либо процентное значение, либо сообщение об ошибке.

Но это означает, что вашей фактической рабочей функции необходимо, чтобы каждый так часто помещал информацию в хэш-карту относительно того, где она есть, поэтому я предложил использовать параллельный хэш-файл, так что вам не нужно беспокоиться о параллельном пишет, и поэтому блокирует соображения.

+0

thx для ответа, но я до сих пор не понимаю, как получить процесс и сделать дело с идентификатором, как вы это делаете? это какая-то функция, или я должен сделать это для себя? – ErVeY

+0

Вам нужно будет сделать это самостоятельно. –

+0

thx для ответа, но я уже храню прогресс в объекте сессии, возможно, не может быть лучшим решением, но он отлично работает, я тоже попробую, всегда приветствую новые знания; D – ErVeY

0

В EJB3.1 @Asynchronous метод-вызовы могут возвращать java.util.concurrent.Future, этот интерфейс предоставляет информацию boolean isCancelled() или boolean isDone(), но никакой информации, если исполнение началось. С моей точки зрения, нет способа получить информацию, если процесс начал свое выполнение через EJB-Container стандартными способами.

+0

да, я знаю о java.util .concurrent.future и я попытался установить свойство bean-компонента с доступом и доступом с помощью метода getter, но я получаю 0% -ый ответ до завершения задачи, а затем я получил 100% , возможно, если я сохраню его в объект сеанса, к которому я мог бы получить доступ, любой sugest ?? – ErVeY

1

Решение, которое я нашел, представляет собой объект контекста, совместно используемый асинхронным методом и основным потоком. Вот пример:

Асинхронный сама работа:

@Stateless 
public class AsyncRunner implements AsyncRunnerLocal { 
    @Asynchronous 
    public Future<ResultObject> doWorkAsynchronous(WorkContext context) { 
     context.setRunning(true); 
     for (int i = 0; i < 100; i++) { 
      //Do the next iteration of your work here 
      context.setProgress(i); 
     } 
     context.setRunning(false); 
     return new AsyncResult(new ResultObject()); 
    } 
} 

Общий объект контекста. Важное значение здесь - ключевое слово volatile. Значения полей будут локально кэшировать в каждом потоке без него и прогресса не будет видно в основном потоке: например

public class WorkContext { 
    //volatile is important! 
    private volatile Integer progress = 0; 
    private volatile boolean running = false; 
    //getters and setters are omitted 
} 

Использование:

public class ProgressChecker { 
    @EJB 
    private AsyncRunnerLocal asyncRunner; 

    private WorkContext context; 
    private Future<ResultObject> future; 

    public void startJob() { 
     this.context = new WorkContext(); 
     future = asyncRunner.doWorkAsynchronous(this.context); 
     //the job is running now 
     while (!future.isDone()) { 
      System.out.println("Progress: " + this.context.getProgress()); 
      Thread.sleep(1000); //try catch is omitted 
     } 
    } 
} 
Смежные вопросы