org.eclipse.flux.core.KeepAliveConnector.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.flux.core.KeepAliveConnector.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Pivotal Software, Inc. and others.
 * All rights reserved. This program and the accompanying materials are made 
 * available under the terms of the Eclipse Public License v1.0 
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
 * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 
 *
 * Contributors:
 *     Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.flux.core;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.flux.client.IChannelListener;
import org.eclipse.flux.client.IMessageHandler;
import org.eclipse.flux.client.MessageConnector;
import org.eclipse.flux.client.MessageHandler;
import org.json.JSONException;
import org.json.JSONObject;

public final class KeepAliveConnector {

    private static final String SERVICE_REQUIRED_REQUEST = "serviceRequiredRequest";
    private static final String SERVICE_REQUIRED_RESPONSE = "serviceRequiredResponse";

    private static final long KEEP_ALIVE_DELAY = 3 * 60 * 60; // 3 hours
    private static final long KEEP_ALIVE_RESPONSE_WAIT_TIME = 5; // 5 seconds

    private ChannelSwitcher channelSwitcher;
    private MessageConnector messageConnector;
    private String serviceTypeId;
    private ScheduledExecutorService executor;
    private ScheduledFuture<?> scheduledKeepAliveMessage = null;
    private ScheduledFuture<?> scheduledShutDown = null;
    private long keepAliveDelay;
    private long keepAliveResponseTimeout;
    private List<MessageHandler> messageHandlers = Collections.emptyList();
    private IMessageHandler keepAliveResponseHandler = new MessageHandler(SERVICE_REQUIRED_RESPONSE) {
        @Override
        public void handle(String messageType, JSONObject message) {
            unsetScheduledShutdown();
            setKeepAliveDelayedMessage();
        }
    };
    private IChannelListener channelListener = new IChannelListener() {
        @Override
        public void connected(String userChannel) {
            unsetScheduledShutdown();
            unsetKeepAliveDelayedMessage();
            setKeepAliveDelayedMessage();
        }

        @Override
        public void disconnected(String userChannel) {
            unsetScheduledShutdown();
            unsetKeepAliveDelayedMessage();
            /*
             * If no channel is connected than keep alive broadcast will
             * definitely not get any replies and shutdown would occur
             */
            setKeepAliveDelayedMessage();
        }
    };

    public KeepAliveConnector(ChannelSwitcher switcher, MessageConnector mc, String serviceTypeId) {
        this(switcher, mc, serviceTypeId, KEEP_ALIVE_DELAY, KEEP_ALIVE_RESPONSE_WAIT_TIME);
    }

    public KeepAliveConnector(ChannelSwitcher switcher, MessageConnector mc, String serviceTypeId,
            long keepAliveDelay, long keepAliveResponseTimeout) {
        this.channelSwitcher = switcher;
        this.messageConnector = mc;
        this.serviceTypeId = serviceTypeId;
        this.executor = Executors.newScheduledThreadPool(2);
        this.keepAliveDelay = keepAliveDelay;
        this.keepAliveResponseTimeout = keepAliveResponseTimeout;
        this.messageConnector.addMessageHandler(keepAliveResponseHandler);
        setKeepAliveDelayedMessage();
        mc.addChannelListener(channelListener);
    }

    private synchronized void unsetKeepAliveDelayedMessage() {
        if (scheduledKeepAliveMessage != null && !scheduledKeepAliveMessage.isCancelled()) {
            scheduledKeepAliveMessage.cancel(false);
        }
    }

    private synchronized void unsetScheduledShutdown() {
        if (scheduledShutDown != null && !scheduledShutDown.isCancelled()) {
            scheduledShutDown.cancel(false);
        }
    }

    private synchronized void setKeepAliveDelayedMessage() {
        scheduledKeepAliveMessage = this.executor.schedule(new Runnable() {
            @Override
            public void run() {
                setScheduledShutdown();
            }
        }, keepAliveDelay, TimeUnit.SECONDS);
    }

    private synchronized void setScheduledShutdown() {
        try {
            scheduledShutDown = executor.schedule(new Runnable() {
                @Override
                public void run() {
                    /*
                     * Clean up needs to be done right before disconnecting from
                     * channel would work here
                     */
                    //mc.connectChannel(Constants.SUPER_USER);
                    System.exit(0);
                }
            }, keepAliveResponseTimeout, TimeUnit.SECONDS);
            JSONObject message = new JSONObject();
            message.put("username", channelSwitcher.getChannel());
            message.put("service", serviceTypeId);
            messageConnector.send(SERVICE_REQUIRED_REQUEST, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void dispose() {
        messageConnector.removeChannelListener(channelListener);
        unsetScheduledShutdown();
        unsetKeepAliveDelayedMessage();
        executor.shutdown();
        messageConnector.removeMessageHandler(keepAliveResponseHandler);
        for (IMessageHandler messageHandler : messageHandlers) {
            messageConnector.removeMessageHandler(messageHandler);
        }
    }

}