У меня следующая ситуация (работает на JBoss AS6 и AS7):

  • Singleton EJB с запланированным методом.
  • Внедренное событие типа SomethingChangedEvent

Рассмотрим следующие примеры:

@Singleton
public final class Scheduler {
    @Inject
    private Event<SomethingChangedEvent> event;

    @Schedule
    private void scheduleSomething() {
        event.fire(new SomethingChangedEvent());
    }
}

Я ожидал, что это событие будет добавлено в какую-то очередь на сервере и распределено им. Все методы, которые наблюдают такого рода события с помощью @Observers, будут уведомлены. Метод event.fire() вернется немедленно.

Однако я сталкиваюсь со следующей проблемой: иногда для возврата к методу event.fire() требуется около двух или трех минут, что вызывает хаос в моем расписании, поскольку предполагается, что он вызывается каждые десять секунд.

Возникает вопрос: как это возможно? Что происходит с событиями, которые запускаются, но их никто не наблюдает? Есть ли очередь, которая может переполниться?

С уважением, Свен

7
Sven Plath 24 Янв 2013 в 14:53

1 ответ

Лучший ответ

Обработка событий CDI происходит синхронно. На самом деле существует предложение о включении модели асинхронной обработки в спецификацию, но по нему все еще идет голосование. А пока есть два способа "принудить" асинхронную обработку:

  1. Используйте JMS - да, это беспорядок, потому что он возвращается к более старым технологиям Java EE. Но это работает
  2. Используйте метод @Asynchronous для методов производителя и наблюдателя, разделите эти вызовы методов на отдельные потоки, управляемые контейнером.

Применение второго метода к вашему примеру кода:

@Singleton
public final class Scheduler {
    @Inject
    private Event<SomethingChangedEvent> event;

    @Asynchronous
    private void scheduleSomething() {
        event.fire(new SomethingChangedEvent());
    }
}
7
Arjan Tijms 26 Янв 2013 в 01:08
Очень интересно. Это решило мою проблему (надеюсь :)). Фактически, метод, наблюдавший за событием, застрял.
 – 
Sven Plath
29 Янв 2013 в 19:42
Я использовал метод 2., и не было необходимости отмечать производителя Asyncronous.
 – 
Dombi Bence
13 Май 2022 в 16:36