服务器重启后Liferay Scheduler无法正常工作 [英] Liferay Scheduler not working after server restart

查看:121
本文介绍了服务器重启后Liferay Scheduler无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码安排工作.

I am scheduling a job using the code below.

@Controller
@RequestMapping("VIEW")
public class MyController {

    @RenderMapping
    public String defaultView() {
        try {
            String cronText = "0 30 12 1/1 * ? *";
            String description = "Message Scheduler Description";
            String destinationName = DestinationNames.SCHEDULER_DISPATCH;
            int exceptionsMaxSize = 0;
            String portletId = "portletId";

            Message message = new Message();
            message.put(SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME,SchedulerListener.class.getName());
            message.put(SchedulerEngine.PORTLET_ID, portletId);

            Trigger trigger = new CronTrigger(SchedulerListener.class.getName(), SchedulerListener.class.getName(), cronText);
            SchedulerEngineHelperUtil.schedule(trigger,StorageType.PERSISTED, description, destinationName, message, exceptionsMaxSize);
        }catch (SchedulerException e) {
            e.printStackTrace();
        }
        return "view";
    }
}

上述代码的问题在于,调度程序仅在服务器会话之前才有效.一旦执行了此方法,即使在服务器重新启动后,我也想在上述时间触发schedulerjob.有没有办法在liferay中实现这一点?

The problem with the above code is that the scheduler is valid only till the server session. Once this method is executed, I want to trigger the schedulerjob at the mentioned time even after a server restart. Is there a way to implement this in liferay?

推荐答案

这似乎与Liferay计划的实现有关. Quartz正确地存储和恢复了触发器和工作.但是Liferay不会将您的MessageListener用作工作.而是将您的MessageListener包装在MessageSenderJob中,并注册您的MessageListener.

This seems to be an issue with the implementation of Liferay scheduling. Quartz is correctly storing and restoring your trigger and the job. But Liferay isn't using your MessageListener as a job. Instead it will wrap your MessageListener in a MessageSenderJob and it will register your MessageListener.

MessageSenderJob在重新启动后仍将被触发,它将把您的消息发送到消息总线.但是,如果您直到那时仍未注册MessageListener,则它们将不会成为该消息的接收者.

The MessageSenderJob will still be triggered after restart, and it will send your message to the message bus. But if you didn't registered your MessageListener until that point, their will be no receiver of that message.

解决方案:您将必须在每次启动时注册MessageListener.通过再次调用调度SchedulerEngineHelperUtil.schedule或通过调用MessageBusUtil.registerMessageListener.请参阅我的问题这里以获取一些注册启动操作的选项.

Solution: You will have to register your MessageListener on every startup. Either by calling scheduling SchedulerEngineHelperUtil.schedule again, or by calling MessageBusUtil.registerMessageListener. See my question here for some options to register startup actions.

如果您要动态创建触发器(由于用户界面中的某些操作),请参见以下示例:

Here an example in case you want to create the trigger dynamically (due to some action in the UI):

@WebListener
public class SchedulerListener implements ServletContextListener, PortalLifecycle, MessageListener {

    private SchedulerEventMessageListenerWrapper listenerWrapper;

    public void contextInitialized(final ServletContextEvent sce) {
        // Wait until the portal is ready
        PortalLifecycleUtil.register(this, PortalLifecycle.METHOD_INIT);
    }

    public void portalInit() {
        // Register our listener
        listenerWrapper = new SchedulerEventMessageListenerWrapper();

        listenerWrapper.setGroupName(getClass().getName());
        listenerWrapper.setJobName(getClass().getName());
        listenerWrapper.setMessageListener(this);

        listenerWrapper.afterPropertiesSet();

        MessageBusUtil.registerMessageListener(DestinationNames.SCHEDULER_DISPATCH, listenerWrapper);
    }

    public void contextDestroyed(final ServletContextEvent event) {
        // Unregister
        if (listenerWrapper != null) {
            MessageBusUtil.unregisterMessageListener(DestinationNames.SCHEDULER_DISPATCH, listenerWrapper);
        }
    }

    public void portalDestroy() {
        // Ignore
    }

    public void receive(final Message message) {
        // ... your job code here ...
    }

}

如果您想使用固定的触发器,则可以放下listenerWrapper并将问题中的SchedulerEngineHelperUtil.schedule(...)代码放入portalInit().

If you want to have a fixed trigger instead, you can drop the listenerWrapper and put your SchedulerEngineHelperUtil.schedule(...) code from your question into portalInit().

如果您想知道,StorageType.PERSISTED的意义是什么:它用于执行在服务器停机时已触发或在服务器停机时刚刚启动的触发器.

If you want to know, what's the point of StorageType.PERSISTED: It's for executing triggers that would have been fired while the server was down or that had just started as the server was going down.

这篇关于服务器重启后Liferay Scheduler无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆