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

com.sproutsocial.nsq.ListBasedBalanceStrategy Maven / Gradle / Ivy

There is a newer version: 1.4.8
Show newest version
package com.sproutsocial.nsq;

import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;

import static com.sproutsocial.nsq.Util.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

public class ListBasedBalanceStrategy extends BasePubSub implements BalanceStrategy {
    private static final Logger logger = getLogger(ListBasedBalanceStrategy.class);
    protected final List daemonList;
    private final Publisher parent;
    private final Function, NsqdInstance> nsqdInstanceSelector;
    private int failoverDurationSecs = 300;

    /**
     * Create a list based failover strategy that will alternate between all connected nsqd.  Will reconnect to a
     * disconnected or failed nsqd on the next publish that could be routed to that nsqd after the failoverDuration has
     * expired (Default 5 min).
     * 

* This will throw an NSQD exception if all nsqd are in a failed state. * * @param nsqd a list of strings that represent HostAndPort objects. */ public static BiFunction getRoundRobinStrategyBuilder(List nsqd) { return (c, p) -> buildRoundRobinStrategy(c, p, nsqd); } /** * Create a list based failover strategy that shows strong preference to the first nsqd on the list. *

* On publish, find the first nsqd in this list that is in a connected or connectable state. A nsqd is connectable * if it has previously failed more than the configured failoverDuration (Default 5 min). *

* This will throw an NSQD exception if all nsqd are in a failed state. * * @param nsqd a list of strings that represent HostAndPort objects. */ public static BiFunction getFailoverStrategyBuilder(List nsqd) { return (c, p) -> buildFailoverStrategy(c,p,nsqd); } private static ListBasedBalanceStrategy buildRoundRobinStrategy(Client client, Publisher parent, List nsqd) { return new ListBasedBalanceStrategy(client, parent, nsqd, new Function, NsqdInstance>() { private int nextDaemonIndex = 0; @Override public NsqdInstance apply(List daemonList) { for (int attempts = 0; attempts < daemonList.size(); attempts++) { NsqdInstance candidate = daemonList.get(nextDaemonIndex); boolean candidateReady = candidate.makeReady(); nextDaemonIndex++; if (nextDaemonIndex >= daemonList.size()) { nextDaemonIndex = 0; } if (candidateReady) { return candidate; } } // We've gotten to the point where all connections have been marked as 'failed'. Rather than intentionally // dropping messages on the floor, let's at least attempt to reconnect for subsequent message publishing. clearAllConnections(daemonList); throw new NSQException("publish failed: Unable to establish a connection with any NSQ host: " + daemonList); } }); } private static ListBasedBalanceStrategy buildFailoverStrategy(Client client, Publisher parent, List nsqd) { return new ListBasedBalanceStrategy(client, parent, nsqd, daemonList -> { for (int attempts = 0; attempts < daemonList.size(); attempts++) { NsqdInstance candidate = daemonList.get(attempts); if (candidate.makeReady()) { return candidate; } } // We've gotten to the point where all connections have been marked as 'failed'. Rather than intentionally // dropping messages on the floor, let's at least attempt to reconnect for subsequent message publishing. clearAllConnections(daemonList); throw new NSQException("publish failed: Unable to establish a connection with any NSQ host: " + daemonList); }); } private static void clearAllConnections(final List daemonList) { for (final NsqdInstance daemon : daemonList) { daemon.clearConnection(); } } public ListBasedBalanceStrategy(Client client, Publisher parent, List nsqd, Function, NsqdInstance> nsqdInstanceSelector) { super(client); checkNotNull(parent); checkNotNull(nsqd); checkNotNull(nsqdInstanceSelector); this.parent = parent; this.nsqdInstanceSelector = nsqdInstanceSelector; List nsqdInstance = new ArrayList<>(); for (String host : nsqd) { if (host != null) nsqdInstance.add(new NsqdInstance(host, this.parent, this.failoverDurationSecs, this)); } daemonList = Collections.unmodifiableList(nsqdInstance); } @Override public NsqdInstance getNsqdInstance() { return nsqdInstanceSelector.apply(daemonList); } @Override public synchronized void connectionClosed(PubConnection closedCon) { for (NsqdInstance daemon : daemonList) { if (daemon.getCon() == closedCon) { daemon.clearConnection(); logger.debug("removed closed publisher connection:{}", closedCon.getHost()); } } } @Override public int getFailoverDurationSecs() { return this.failoverDurationSecs; } @Override public void setFailoverDurationSecs(int failoverDurationSecs) { this.failoverDurationSecs = failoverDurationSecs; for (NsqdInstance nsqdInstance : daemonList) { nsqdInstance.setFailoverDurationSecs(failoverDurationSecs); } } @Override public String toString() { return this.getClass().getSimpleName() + "{" + "daemonList=" + daemonList + ", failoverDurationSecs=" + failoverDurationSecs + '}'; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy