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

org.ow2.cmi.lb.policy.RoundRobin Maven / Gradle / Ivy

There is a newer version: 2.2.6
Show newest version
/**
 * CMI : Cluster Method Invocation
 * Copyright (C) 2007,2008 Bull S.A.S.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id:DefaultLBPolicy.java 949 2007-06-02 17:24:33Z loris $
 * --------------------------------------------------------------------------
 */

package org.ow2.cmi.lb.policy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

import net.jcip.annotations.ThreadSafe;

import org.ow2.cmi.lb.LoadBalanceable;
import org.ow2.cmi.lb.NoLoadBalanceableException;
import org.ow2.cmi.lb.strategy.IStrategy;
import org.ow2.cmi.lb.strategy.NoStrategy;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
 * The default load-balancing policy (Round Robin) that always chooses the next available load-balanceable.
 * @param  The type of objects that are load-balanced
 * @author The new CMI team
 */
@ThreadSafe
public final class RoundRobin extends AbstractPolicy {

    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(RoundRobin.class);

    /**
     * Initial value of the pointer.
     */
    private static final int INITIAL_VALUE = -1;

    /**
     * The pointer to store the last ref.
     */
    private int pointer;


    /**
     * Random numbers.
     */
    private final Random rand = new Random();

    /**
     * Build the Round Robin policy.
     * Give to the pointer an initial value.
     */
    public RoundRobin() {
        pointer = INITIAL_VALUE;
    }

    /**
     * Chooses the next load-balanceable among the list of load-balanceables.
     * @param loadBalanceables the list of load-balanceables
     * @throws NoLoadBalanceableException if no server available
     * @return the chosen load-balanceable
     */
    @Override
    public synchronized T choose(final Collection loadBalanceables) throws NoLoadBalanceableException{

        if (loadBalanceables == null || loadBalanceables.isEmpty()) {
            LOGGER.error("The given list is null or empty: " + loadBalanceables);
            throw new NoLoadBalanceableException("The given list is null or empty: " + loadBalanceables);
        }
        List cmiRefsWithStrategy;

        IStrategy strategy = getStrategy();

        if(strategy != null) {
            cmiRefsWithStrategy = strategy.choose(loadBalanceables);
            // If no server corresponds at this strategy, we don't use it
            if(cmiRefsWithStrategy.isEmpty()) {
                cmiRefsWithStrategy = new ArrayList(loadBalanceables);
            }
        } else {
            cmiRefsWithStrategy = new ArrayList(loadBalanceables);
        }

        int size = cmiRefsWithStrategy.size();

        if(pointer == INITIAL_VALUE){
            // The initial pointer depends on the strategy
            if(strategy != null && !(strategy instanceof NoStrategy)) {
                // Use the first element chosen by the strategy
                pointer = 0;
            } else {
                // No strategy, choose randomly the first element
                pointer = rand.nextInt(size);
            }
        } else {
            // Perhaps some servers are disappeared, in this case the pointer can out of bounds
            if(pointer >= size) {
                pointer = INITIAL_VALUE;
            }
            // Choose the next target
            pointer = (pointer + 1) % size;
        }
        return cmiRefsWithStrategy.get(pointer);
    }

    @Override
    public String toString() {
        return "RoundRobin[pointer: "
        + pointer + " - strategy: " + getStrategy() + "]";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy