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

graphql.servlet.internal.ApolloSubscriptionKeepAliveRunner Maven / Gradle / Ivy

There is a newer version: 16.0.0
Show newest version
package graphql.servlet.internal;

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

import javax.websocket.Session;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

class ApolloSubscriptionKeepAliveRunner {

    private static final Logger LOG = LoggerFactory.getLogger(ApolloSubscriptionKeepAliveRunner.class);

    private static final int EXECUTOR_POOL_SIZE = 10;

    private final ScheduledExecutorService executor;
    private final SubscriptionSender sender;
    private final ApolloSubscriptionProtocolHandler.OperationMessage keepAliveMessage;
    private final Map> futures;
    private final long keepAliveIntervalSeconds;

    ApolloSubscriptionKeepAliveRunner(SubscriptionSender sender, Duration keepAliveInterval) {
        this.sender = Objects.requireNonNull(sender);
        this.keepAliveMessage = ApolloSubscriptionProtocolHandler.OperationMessage.newKeepAliveMessage();
        this.executor = Executors.newScheduledThreadPool(EXECUTOR_POOL_SIZE);
        this.futures = new ConcurrentHashMap<>();
        this.keepAliveIntervalSeconds = keepAliveInterval.getSeconds();
    }

    void keepAlive(Session session) {
        futures.computeIfAbsent(session, this::startKeepAlive);
    }

    private ScheduledFuture startKeepAlive(Session session) {
        return executor.scheduleAtFixedRate(() -> {
            try {
                if (session.isOpen()) {
                    sender.send(session, keepAliveMessage);
                } else {
                    LOG.warn("Session appears to be closed. Aborting keep alive");
                    abort(session);
                }
            } catch (Throwable t) {
                LOG.error("Cannot send keep alive message. Aborting keep alive", t);
                abort(session);
            }
        }, 0, keepAliveIntervalSeconds, TimeUnit.SECONDS);
    }

    void abort(Session session) {
        Future future = futures.remove(session);
        if (future != null) {
            future.cancel(true);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy