Package org.xmlBlaster.engine.cluster.simpledomain

Source Code of org.xmlBlaster.engine.cluster.simpledomain.RoundRobin

/*------------------------------------------------------------------------------
Name:      RoundRobin.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
Comment:   Simple demo implementation for clustering
Author:    xmlBlaster@marcelruff.info
------------------------------------------------------------------------------*/
package org.xmlBlaster.engine.cluster.simpledomain;

import java.util.logging.Logger;
import java.util.logging.Level;
import org.xmlBlaster.util.plugin.I_Plugin;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.engine.ServerScope;
import org.xmlBlaster.engine.cluster.I_LoadBalancer;
import org.xmlBlaster.engine.cluster.NodeMasterInfo;
import org.xmlBlaster.engine.cluster.ClusterManager;

import java.util.Set;
import java.util.Iterator;

/**
* Implements dummy load balancing for xmlBlaster using round robin approach.
* @author xmlBlaster@marcelruff.info
* @since 0.79e
*/
final public class RoundRobin implements I_LoadBalancer, I_Plugin {

   private String ME = "RoundRobin";
   private ServerScope glob = null;
   private static Logger log = Logger.getLogger(RoundRobin.class.getName());
   private int counter = 0;

   /**
    * This is called after instantiation of the plugin
    * @param glob The Global handle of this xmlBlaster server instance.
    */
   public void initialize(ServerScope glob, ClusterManager clusterManager) {
      this.glob = glob;

      this.ME = this.ME + "-" + glob.getId();
      log.info("Round robin load balancer is initialized");
   }

   /**
    * This method is called by the PluginManager (enforced by I_Plugin).
    * @see org.xmlBlaster.util.plugin.I_Plugin#init(org.xmlBlaster.util.Global,org.xmlBlaster.util.plugin.PluginInfo)
    */
   public void init(org.xmlBlaster.util.Global glob, org.xmlBlaster.util.plugin.PluginInfo pluginInfo) {
   }

   /**
    * Return plugin type for Plugin loader
    * @return "RoundRobin"
    */
   public String getType() {
      return "RoundRobin";
   }

   /**
    * Return plugin version for Plugin loader
    * @return "1.0"
    */
   public String getVersion() {
      return "1.0";
   }

   /**
    * Get a human readable name of this filter implementation
    * @return "RoundRobin"
    */
   public String getName() {
      return "RoundRobin";
   }

   /**
    * We determine which xmlBlaster node to choose with a simple counter.
    * <p />
    * @param nodeMasterInfoSet A set containing NodeMasterInfo objects, the possible xmlBlaster nodes.
    *                       Is never null, but may have a size of 0.
    * @return The chosen nodeMasterInfo to handle the message or null to handle it locally
    * @see org.xmlBlaster.engine.cluster.I_LoadBalancer#getClusterNode(java.util.Set)
    */
   public synchronized NodeMasterInfo getClusterNode(Set nodeMasterInfoSet) throws XmlBlasterException {

      // TODO: Change return to NodeMasterInfo[] if multiple fail over nodes exist !!!
     
      if (nodeMasterInfoSet.size() == 0) {
         log.warning("Empty nodeMasterInfoSet, using local node");
         return null; // clusterManager.getMyClusterNode(); // handle locally
      }

      if (counter >= nodeMasterInfoSet.size()) // counter is our RoundRobin approach
         counter = 0;

      /*
       The Set is sorted after
       "<available:stratum:nodeId>"
       available := 0 connected, 1 polling, 2 unavailable
       stratum   := 0 master, 1 stratum, 2 stratum ...

       So we may choose a slave routing to a master,
       the chosen stratum must be smaller (closer to the master) than our current stratum
      
       There must be the possibility to use a slave instead of the master
       directly (choosing the stratum which is exactly one smaller?)
      */

      // Step 1: Find out my stratum for this message (if i have one)
      // Check all rules to find my lowest stratum
      int myStratum = Integer.MAX_VALUE;
      Iterator it = nodeMasterInfoSet.iterator();
      while (it.hasNext()) {
         NodeMasterInfo nodeMasterInfo = (NodeMasterInfo)it.next();
         if (nodeMasterInfo.getClusterNode().isLocalNode()) {
            if (nodeMasterInfo.getStratum() < myStratum) {
               myStratum = nodeMasterInfo.getStratum();
               break;
            }
         }
      }

      // Step 2: Take the node with the lowest stratum or myself
      // Aaheem, this is no round robin ... :-)
      // We know that the Set is sorted after available:stratum:nodeId
      it = nodeMasterInfoSet.iterator();
      while (it.hasNext()) {
         NodeMasterInfo nodeMasterInfo = (NodeMasterInfo)it.next();
         if (myStratum <= nodeMasterInfo.getStratum()) {
            // handle locally, no need to send to a worse or equal stratum
            if (nodeMasterInfo.getStratum() > 0) {
               log.warning("Selected myself as master node from a choice of " + nodeMasterInfoSet.size()
                    + " nodes, but we are only stratum=" + nodeMasterInfo.getStratum() + ". The message is not routed further!");
            }
            else {
               if (log.isLoggable(Level.FINE)) log.fine("Selected myself as master node from a choice of " + nodeMasterInfoSet.size() + " nodes");
            }
            return null; // handle locally: clusterManager.getMyClusterNode();
         }

         if (log.isLoggable(Level.FINE))
            log.fine("Selected master node id='" +
                     nodeMasterInfo.getClusterNode().getId() + "' from a choice of " +
                     nodeMasterInfoSet.size() + " nodes.  alive = " +
                     nodeMasterInfo.getClusterNode().isAlive() + ", polling = " +
                     nodeMasterInfo.getClusterNode().isPolling());

         return nodeMasterInfo;
      }

      /*
      // Step 2: Filter the possible nodes (round robin)
      it = nodeMasterInfoSet.iterator();
      int ii=0;
      while (it.hasNext()) {
         Object obj = it.next();
         if (ii == counter) {
            NodeMasterInfo nodeMasterInfo = (NodeMasterInfo)obj;
            ClusterNode clusterNode = nodeMasterInfo.getClusterNode();
            if (log.isLoggable(Level.FINE)) log.trace(ME, "Selected master node id='" + clusterNode.getId() + "' from a choice of " + nodeMasterInfoSet.size() + " nodes");
            counter++;
            return clusterNode;
         }
         ii++;
      }
      */

      log.warning("Can't find master, using local node");
      return null; // handle locally: clusterManager.getMyClusterNode();
   }

   public void shutdown() throws XmlBlasterException {
   }
}
TOP

Related Classes of org.xmlBlaster.engine.cluster.simpledomain.RoundRobin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.