Timer Service in ejb 3.1 - schedule calling timeout issue

安稳与你 提交于 2019-11-29 22:36:33

问题


I have created simple example with @Singleton, @Schedule and @Timeout annotations to try if they would solve my problem.

The scenario is this: EJB calls 'check' function every 5 secconds, and if certain conditions are met it will create single action timer that would invoke some long running process in asynchronous fashion. (it's sort of queue implementation type of thing). It then continues to check, but while the long running process is there it won't start another one.

Below is the code I came up with, but this solution does not work, because it looks like asynchronous call I'm making is in fact blocking my @Schedule method.

@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");

    }

What am I missing here or should I try different aproach? Any ideas most welcome :)

Testing with Glassfish 3.0.1 latest build - forgot to mention


回答1:


The default @ConcurrencyManagement for singletons is ConcurrencyManagementType.CONTAINER with default @Lock of LockType.WRITE. Basically, that means every method (including generateReports) is effectively marked with the synchronized keyword, which means that checkQueueState will block while generateReport is running.

Consider using ConcurrencyManagement(ConcurrencyManagementType.BEAN) or @Lock(LockType.READ). If neither suggestion helps, I suspect you've found a Glassfish bug.

As an aside, you probably want persistent=false since you probably don't need to guarantee that the checkQueueState method fires every 5 seconds even when your server is offline. In other words, you probably don't need the container to fire "catch ups" when you bring your server back online.



来源:https://stackoverflow.com/questions/2691835/timer-service-in-ejb-3-1-schedule-calling-timeout-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!