Есть ли способ узнать ход асинхронного процесса EJB? - PullRequest
4 голосов
/ 31 июля 2010

Я пытаюсь получить процент прогресса от асинхронного процесса EJB. Возможно ли это?

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

Ответы [ 3 ]

2 голосов
/ 31 июля 2010

Узнать ход асинхронных процессов всегда сложно, особенно если вы не знаете, запущены ли они на самом деле.

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

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

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

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

ОБНОВЛЕНИЕ:

В вашем интерфейсе создайте новую функцию

String progressDone(String id);

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

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

1 голос
/ 22 августа 2017

Решение, которое я нашел, - это объект контекста, общий для асинхронного метода и основного потока.Вот пример:

Само асинхронное задание:

@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());
    }
}

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

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
        }
    }
}
0 голосов
/ 01 августа 2010

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

...