Package org.prevayler.cluster

Source Code of org.prevayler.cluster.Node

package org.prevayler.cluster;

import org.jgroups.*;
import org.jgroups.blocks.*;
import org.jgroups.util.Util;
import org.prevayler.cluster.ClusterListener;

import java.io.Serializable;
import java.util.Vector;

public class Node implements RequestHandler, MessageListener, MembershipListener {
  private static final String LOCK_ID = "BroadCastLock";
  private static final String MESSAGE_CHANNEL_PROPERTIES = "UDP(mcast_addr=228.8.8.8;mcast_port=45566;ip_ttl=32;" +
      "mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" +
      "PING(timeout=2000;num_initial_members=3):" +
      "MERGE2(min_interval=5000;max_interval=10000):" +
      "FD_SOCK:" +
      "VERIFY_SUSPECT(timeout=1500):" +
      "pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):" +
      "UNICAST(timeout=5000):" +
      "pbcast.STABLE(desired_avg_gossip=20000):" +
      "FRAG(frag_size=4096;down_thread=false;up_thread=false):" +
      "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
      "shun=false;print_local_addr=true):" +
      "pbcast.STATE_TRANSFER";

  static final String LOCK_CHANNEL_PROPERTIES = ""
      + "UDP(mcast_addr=228.3.11.76;mcast_port=12345;ip_ttl=1;"
      + "mcast_send_buf_size=150000;mcast_recv_buf_size=80000)"
      + ":PING(timeout=500;num_initial_members=1)"
      + ":FD"
      + ":VERIFY_SUSPECT(timeout=1500)"
      + ":pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800)"
      + ":UNICAST(timeout=5000)"
      + ":pbcast.STABLE(desired_avg_gossip=200)"
      + ":FRAG(frag_size=4096)"
      + ":pbcast.GMS(join_timeout=5000;join_retry_timeout=1000;"
      + "shun=false;print_local_addr=false)";


  private JChannel channel;
  private JChannel lockChannel;
  private MessageDispatcher dispatcher;
  private ClusterListener listener;
  private DistributedLockManager distributedLockManager;
  private static final Object broadcastLock = new Object();

  public Node() {
    this(null);
  }

  public Node(ClusterListener listener) {
    try {
      lockChannel = new JChannel(LOCK_CHANNEL_PROPERTIES);
      distributedLockManager = new DistributedLockManager(new VotingAdapter(lockChannel),
          String.valueOf(System.currentTimeMillis()));
      lockChannel.connect(Node.class.getName() + "Lock");

      Thread.sleep(1000);

      this.listener = listener;
      channel = new JChannel(MESSAGE_CHANNEL_PROPERTIES);
      channel.setOpt(Channel.GET_STATE_EVENTS, new Boolean(true));
      dispatcher = new MessageDispatcher(channel, this, this, this);
      channel.connect(Node.class.getName());

      acquireClusterWideLock();
      channel.getState(null, 0);

      Thread.sleep(1000);

    } catch (Exception e) {
      throw new RuntimeException(e.toString());
    }
  }

  public void viewAccepted(View view) {
    System.out.println("Members " + view.size());
  }

  public void suspect(Address suspected_mbr) {
  }

  public void block() {
  }

  public void receive(Message msg) {
  }

  public byte[] getState() {
    System.out.println("Getting state");
    if (listener != null) {
      try {
        return Util.objectToByteBuffer(listener.getState());
      } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.toString());
      }
    }
    return null;
  }

  public void setState(byte[] state) {
    System.out.println("Setting state");
    try {
      if (listener != null) {
        listener.setState(Util.objectFromByteBuffer(state));
      }
    } catch (Exception e) {
      throw new RuntimeException(e.toString());
    } finally {
      try {
        // unlock cluster, lock acquired when state was requested
        releaseClusterWideLock();
      } catch (ChannelException e) {
        e.printStackTrace();
      }
    }
  }

  public void waitForConnection() throws InterruptedException {
    broadcast("Node Connecting");
  }

  public int getNumberOfNodesInCluster() {
    return channel.getView().getMembers().size();
  }

  public void broadcast(Serializable message) {
    try {
      acquireClusterWideLock();
      synchronized (broadcastLock) {
        System.out.println("Broadcasting " + message);
        dispatcher.castMessage(null, new Message(null, null, message), GroupRequest.GET_ALL, 0);
      }
      releaseClusterWideLock();
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e.toString());
    }
  }

  private void releaseClusterWideLock() throws ChannelException {
    System.out.println("Releasing cluster lock");
    boolean lockReleased = false;
    while (!lockReleased) {
      try {
        distributedLockManager.unlock(LOCK_ID, lockChannel.getLocalAddress().toString());
        lockReleased = true;
      } catch (LockNotReleasedException e) {
      }
    }
    System.out.println("Broadcast lock released");
  }

  private void acquireClusterWideLock() throws ChannelException {
    System.out.println("Grabbing cluster lock");
    boolean lockAcquired = false;
    while (!lockAcquired) {
      try {
        distributedLockManager.lock(LOCK_ID, lockChannel.getLocalAddress().toString(), 1000);
        lockAcquired = true;
      } catch (LockNotGrantedException e) {
      }
    }
  }

  public Object handle(Message message) {
    System.out.println("Received message " + message + " on " + getAddress());
    if (listener != null) {
      return listener.receive(message.getObject());
    }
    return null;
  }

  public boolean isMaster() {
    return getAddress().equals(getMasterAddress());
  }

  public Address getMasterAddress() {
    try {
      Vector members = channel.getView().getMembers();
      Address master = (Address) members.firstElement();
      channel.getState(master, 1000);
      return (Address) channel.getView().getMembers().firstElement();
    } catch (Exception e) {
      throw new RuntimeException(e.toString());
    }
  }

  public void shutdown() {
    channel.close();
    lockChannel.close();
    dispatcher.stop();
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
  }

  public void setListener(ClusterListener listener) {
    this.listener = listener;
  }

  public Address getAddress() {
    return channel.getLocalAddress();
  }
}
TOP

Related Classes of org.prevayler.cluster.Node

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.