CDI 2.0: Как проверить, сколько асинхронных событий, запущенных с помощью Event.fireAsync(), может выполняться одновременно

Я пишу веб-сервис REST с использованием Jersey, CDI 2.0 (реализация Weld 3.0.1. Final) и Tomcat. Цель веб-сервиса - запускать длинные вычислительные задачи, которые могут выполняться в течение нескольких минут или даже часов. Задача должна быть запущена с HTTP-запроса POST, отправленного веб-службе, однако запрос должен быть завершен немедленно и отправить ответ клиенту, в то время как запущенная задача должна выполнять свою работу в другом потоке.

Я уже решил это с помощью CDI 2.0 и его Event.fireAsync() метод, позволяющий обрабатывать события асинхронно. Класс ресурсов JAX-RS, который обрабатывает POST-запросы, запускает асинхронное событие, которое затем обрабатывается методом асинхронного наблюдателя (аннотировано @ObservesAsync) в отдельности @ApplicationScoped Боб CDI.

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

Итак, мои вопросы:

  1. Как проверить, сколько потоков доступно для реальной асинхронной обработки событий CDI?
  2. Как проверить, сколько событий находится в очереди и ждать обработки в методе асинхронного наблюдателя?

1 ответ

Решение

По первому вопросу - по умолчанию будут использоваться доступные процессоры. Нечто подобное Runtime.getRuntime().availableProcessors() + 1, Тем не менее, я полагаю, что вам нужны параметры конфигурации. Здесь вы можете выбрать, вы можете:

  • Используйте конфигурацию сварного шва и выбирайте из заранее определенных опций
    • Посмотрите на конфигурационную часть Weld doc
    • Я бы предложил использовать FIXED_TIMEOUT пул (потоки не будут задерживаться, когда не нужны), ключ для этого конфига org.jboss.weld.executor.threadPoolType
    • Вы можете установить желаемое количество потоков, используя клавишу org.jboss.weld.executor.threadPoolSize
    • Проверьте главу 19.1 о том, как передать параметры конфигурации в Weld
  • Определите свой собственный Executor и запускать асинхронные события с помощью NotificationOptions
  • (OVERKILL) Реализуйте свой собственный ExecutorServices, часть Weld SPI

На ваш второй вопрос - я должен вас здесь разочаровать. В Weld пока нет способа достичь этого. Не стесняйтесь создавать проблему WELD Jira, и вы можете увидеть ее в будущем.

Другие вопросы по тегам