JvmCluster.java

  1. package org.microspace.transport.specific;

  2. import java.io.Serializable;
  3. import java.util.HashMap;
  4. import java.util.Map;

  5. import org.microspace.failover.FailoverState;
  6. import org.microspace.util.MicroLogger;

  7. /**
  8.  * Cluster for Jvm Based Transports.
  9.  *
  10.  * @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
  11.  * @version 2016-06-26
  12.  */

  13. public class JvmCluster {
  14.    
  15.     final MicroLogger log = new MicroLogger (JvmCluster.class);
  16.     final String name;
  17.    
  18.     final Map<Integer, JvmTransport> transports = new HashMap<Integer, JvmTransport> ();
  19.    
  20.     public JvmCluster(String name) {
  21.         this.name = name;
  22.     }

  23.     public String getName() {
  24.         return name;
  25.     }
  26.    
  27.     void distribute (int from, Serializable msg, Integer to) {
  28.         if (to != null) {
  29.             if (from == to) {
  30.                 throw new IllegalArgumentException ("Distributed to ourself");
  31.             }
  32.             JvmTransport t = transports.get(to);
  33.             t.distribute (from, msg);
  34.             return;
  35.         }
  36.         for (JvmTransport t : transports.values()) {
  37.             if (t.getId() == from) continue;
  38.             t.distribute (from, msg);
  39.         }
  40.     }
  41.    
  42.     synchronized public void add (JvmTransport transport) {
  43.         if (transports.containsKey(transport.getId())) {
  44.             throw new IllegalArgumentException ("JvmTransport already exists");
  45.         }
  46.         Integer oldPrimary = getOldest ();
  47.         transports.put(transport.getId(), transport);
  48.         Integer newPrimary = getOldest ();
  49.         failover (oldPrimary, newPrimary);
  50.         if (transport.getFailoverState() == FailoverState.INITIALIZING) {
  51.             transport.failoverStateChanged(FailoverState.BACKUP);
  52.         }
  53.     }
  54.    
  55.     synchronized public void remove (JvmTransport transport) {
  56.         if (!transports.containsKey(transport.getId())) {
  57.             return;
  58.         }
  59.         Integer oldPrimary = getOldest ();
  60.         transports.remove(transport.getId());
  61.         Integer newPrimary = getOldest ();
  62.         failover (oldPrimary, newPrimary);
  63.         if (transport.getFailoverState() != FailoverState.BACKUP) {
  64.             transport.failoverStateChanged(FailoverState.BACKUP);
  65.            
  66.         }
  67.     }
  68.    
  69.     private void failover (Integer from, Integer to) {
  70.         log.info("Failover from $* to $*", from, to);
  71.         if (from != null) {
  72.             JvmTransport ft = transports.get(from);
  73.             if (!from.equals(to) && ft != null) {
  74.                 ft.failoverStateChanged(FailoverState.BACKUP);
  75.             }
  76.         }
  77.         if (to != null) {
  78.             JvmTransport ft = transports.get(to);
  79.             if (!to.equals(from)) {
  80.                 ft.failoverStateChanged(FailoverState.PRIMARY);
  81.             }
  82.         }
  83.     }
  84.    
  85.    
  86.     private Integer getOldest() {
  87.         Integer oldest = null;
  88.         for (int id : transports.keySet()) {
  89.             if (oldest == null) {
  90.                 oldest = id;
  91.             } else if (id < oldest) {
  92.                 oldest = id;
  93.             }
  94.         }
  95.         return oldest;
  96.     }
  97.    
  98.     public JvmTransport getOldestTransport() {
  99.         Integer old = getOldest();
  100.         if (old == null) return null;
  101.         return transports.get(old);
  102.     }
  103.    
  104. }