在akka中重新启动已取消的调度程序

时间:2014-02-20 06:47:15

标签: akka scheduler

我刚开始使用Akka并创建了一个测试应用程序。在其中,我创建了一组演员,他们创建了一个调度程序来生成心跳事件。在另一种类型的事件中,我用heartbeat.cancel();取消调度程序,但我想在另一个事件发生时重新启动它。如果我重新创建调度程序,我会发现内存消耗不断增加。

那么问题是如何恢复调度程序或如何正确处理调度程序。

这是该演员的代码

public class Device extends UntypedActor {

    enum CommunicationStatus{
        OK,
        FAIL,
        UNKNOWN
    }

    private static class Heartbeat {

    }

    public final String deviceId;
    private CommunicationStatus commStatus;
    private Cancellable heartBeatScheduler;

    public Device(String Id)
    {
        deviceId = Id;
        commStatus = CommunicationStatus.UNKNOWN;

    }

    @Override
    public void preStart() {
        getContext().system().eventStream().subscribe(getSelf(), DeviceCommunicationStatusUpdated.class);
        startHeartbeat();
    }

    @Override
    public void postStop() {
        stopHeartBeat();
    }

    private void startHeartbeat() {

        LoggingAdapter log = Logging.getLogger(getContext().system(), this);
        log.info("Starting heartbeat");

        heartBeatScheduler = getContext().system().scheduler().
                schedule(Duration.Zero(),
                        Duration.create(1, TimeUnit.SECONDS),
                        getContext().self(),
                        new Heartbeat(),
                        getContext().system().dispatcher(),
                        ActorRef.noSender());
    }

    private void stopHeartBeat() {
        if(!heartBeatScheduler.isCancelled()) {
            LoggingAdapter log = Logging.getLogger(getContext().system(), this);
            log.info("Stopping heartbeat");
            heartBeatScheduler.cancel();
        }
    }

    public String getDeviceId() {
        return deviceId;
    }

    public CommunicationStatus getCommunicationStatus(){
        return commStatus;
    }

    @Override
    public void onReceive(Object message) throws Exception {
        LoggingAdapter log = Logging.getLogger(getContext().system(), this);

        if(message instanceof Heartbeat){
            log.info("Pum, pum");
        }
        else if (message instanceof DeviceCommunicationStatusUpdated){
            DeviceCommunicationStatusUpdated event = (DeviceCommunicationStatusUpdated) message;

            if(event.deviceId == this.deviceId){
                log.info("Received communication status update. '{}' is now {}", deviceId, event.state);
                this.commStatus =
                        event.state == DeviceCommunicationStatusUpdated.State.OK ?
                                CommunicationStatus.OK : CommunicationStatus.FAIL;

                if(commStatus == CommunicationStatus.OK && heartBeatScheduler.isCancelled()){
                    startHeartbeat();
                }
                else {
                    stopHeartBeat();
                }

            }
        }

        else unhandled(message);
    }
}

1 个答案:

答案 0 :(得分:0)

最后没有泄漏,只是我是Java的新手并且对垃圾收集感到不耐烦。无论如何,我想知道调度程序的重置/重启。