Сервис таймера в ejb 3.1 - расписание, называя проблему тайм-аута

Я создал простой пример с @Singleton, @Schedule и @Timeout аннотации, чтобы попробовать, если они решили бы мою проблему.

Сценарий - это: EJB вызывает функцию 'проверки' каждые 5 секунд, и если определенные условия будут соблюдены, то она создаст единственный таймер действия, который вызвал бы некоторый длительный процесс асинхронным способом. (это - вид типа реализации очереди вещи). Это затем продолжает проверять, но в то время как длительный процесс там, это не запустит другой.

Ниже код, который я придумал, но это решение не работает, потому что это похоже на асинхронный вызов, который я выполняю, на самом деле блокирует мой @Schedule метод.

@Singleton
@Startup
public class GenerationQueue {

    private Logger logger = Logger.getLogger(GenerationQueue.class.getName());

    private List<String> queue = new ArrayList<String>();

    private boolean available = true;

    @Resource
    TimerService timerService;

    @Schedule(persistent=true, minute="*", second="*/5", hour="*")
    public void checkQueueState() {

        logger.log(Level.INFO,"Queue state check: "+available+" size: "+queue.size()+", "+new Date());

        if (available) {

            timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false));
        }

    }

    @Timeout
    private void generateReport(Timer timer) {

        logger.info("!!--timeout invoked here "+new Date());

        available = false;

        try {

            Thread.sleep(1000*60*2); // something that lasts for a bit

        } catch (Exception e) {}

        available = true;

        logger.info("New report generation complete");

    }

Что я пропускаю здесь, или я должен попробовать другой подход? Любые приветствующиеся идеи :)

При тестировании с Glassfish 3.0.1 последних сборки - забыли упоминать

5
задан Pool 1 June 2015 в 17:33
поделиться

1 ответ

@ConcurrencyManagement по умолчанию для синглтонов - ConcurrencyManagementType.CONTAINER с @Lock по умолчанию для LockType.WRITE. По сути, это означает, что каждый метод (включая generateReports) эффективно помечается ключевым словом synchronized, что означает, что checkQueueState будет блокироваться во время работы generateReport.

Рассмотрите возможность использования ConcurrencyManagement (ConcurrencyManagementType.BEAN) или @Lock (LockType.READ). Если ни одно из предложений не помогает, я подозреваю, что вы обнаружили ошибку Glassfish.

Кстати, вы, вероятно, захотите persistent = false, поскольку вам, вероятно, не нужно гарантировать, что метод checkQueueState срабатывает каждые 5 секунд, даже когда ваш сервер отключен. Другими словами, вам, вероятно, не нужен контейнер, чтобы «догонять», когда вы снова включаете свой сервер.

11
ответ дан 13 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: