All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.dangernoodle.slack.client.SlackConnectionMonitor Maven / Gradle / Ivy

The newest version!
package io.dangernoodle.slack.client;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


class SlackConnectionMonitor
{
    private static final Logger logger = LoggerFactory.getLogger(SlackConnectionMonitor.class);

    final int heartbeat;

    final boolean reconnect;

    private final SlackClient client;

    private final ScheduledExecutorService executorService;

    private ScheduledFuture future;

    private long lastPingId;

    SlackConnectionMonitor(SlackClient client, int heartbeat, boolean reconnect)
    {
        this.client = client;
        this.heartbeat = heartbeat;
        this.reconnect = reconnect;

        this.executorService = createExecutorService();
    }

    @Override
    protected void finalize() throws Throwable
    {
        executorService.shutdownNow();
        super.finalize();
    }

    // visible for testing
    ScheduledExecutorService createExecutorService()
    {
        return Executors.newSingleThreadScheduledExecutor(this::createThread);
    }

    // visible for testing
    long getLastPingId()
    {
        return lastPingId;
    }

    void run()
    {
        if (client.isConnected() && lastPingId == client.getSession().getLastPingId())
        {
            lastPingId = client.sendPing();
            logger.trace("connection ok, ping sent - id [{}]", lastPingId);
        }
        else if (reconnect)
        {
            logger.trace("issue with connection, reconnecting...");
            reconnect();
        }
        else
        {
            logger.warn("disconnected from slack, reconnect not enabled");
        }
    }

    synchronized void start()
    {
        logger.info("heartbeat thread started at interval of [{}] seconds", heartbeat);
        future = executorService.scheduleAtFixedRate(this::run, 0, heartbeat, TimeUnit.SECONDS);
    }

    synchronized void stop()
    {
        if (future != null)
        {
            future.cancel(true);
            future = null;

            logger.info("hearbeat thread stopped");
        }
    }

    private Thread createThread(Runnable runnable)
    {
        Thread thread = new Thread(runnable);
        thread.setName("Slack-Hearbeat");

        return thread;
    }

    private void reconnect()
    {
        try
        {
            lastPingId = client.reconnect();
            logger.trace("recconnected, ping id [{}]", lastPingId);
        }
        catch (IOException e)
        {
            logger.warn("reconnection failed", e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy