Package org.jgroups.tests

Source Code of org.jgroups.tests.VirtualSynchronyTest$GroupMemberThread

package org.jgroups.tests;


import org.jgroups.*;
import org.jgroups.util.Util;
import org.testng.annotations.Test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
* Virtual Synchrony guarantees that views in a group are observed
* in the same order by all group members and that views are totally ordered
* with respect to all regular messages in a group.
*
* Therefore, in virtually synchronous group communication model, all members
* that observe the same two consecutive views, receive the same set of regular
* multicast messages between those two views.
*
* VirtualSynchronyTest verifies virtual synchrony as follows. Each surviving member P 
* from a view Vm that receives a new view Vn sends a message M to group coordinator Q
* containing number of messages received in view Vm. Each member P upon receiving
* a new view sends a random number of messages to everyone in the group.
*
* Group coordinator Q upon receiving each message M from a member P verifies
* if virtual synchrony is satisifed.
*
*
* @author Vladimir Blagojevic
*
*/
@Test(groups=Global.STACK_INDEPENDENT,sequential=true)
public class VirtualSynchronyTest {

  private final static String CHANNEL_PROPS="flush-udp.xml";
  private final static int INITIAL_NUMBER_OF_MEMBERS=5;
  private int runningTime = 1000*50; // 50 secs
  private Random r = new Random();
 
 

    public void testVSynch() throws Exception
  {
    long start = System.currentTimeMillis();
    boolean running=true;
    List members=new ArrayList();     
   
    //first spawn and join
    for(int i =0;i<INITIAL_NUMBER_OF_MEMBERS;i++)
    {
      GroupMemberThread member = new GroupMemberThread("Member");
      member.start();     
      members.add(member);         
      Util.sleep(getRandomDelayInSeconds(4,6)*1000);
    }
   
   
    for (; running;) {           
     
      //and then flip a coin
      if(r.nextBoolean())
      {
        Util.sleep(getRandomDelayInSeconds(3,8)*1000);
        GroupMemberThread member = new GroupMemberThread("Member");       
        member.start();     
        members.add(member);       
      }
      else if(members.size()>1)
      {
        Util.sleep(getRandomDelayInSeconds(3,8)*1000);
        GroupMemberThread unluckyBastard = (GroupMemberThread) members.get(r.nextInt(members.size()));
        members.remove(unluckyBastard);       
        unluckyBastard.setRunning(false);       
      }       
      running =System.currentTimeMillis() - start <= runningTime;
      System.out.println("Running time " + ((System.currentTimeMillis()-start)/1000) + " secs");
    }
    System.out.println("Done, Virtual Synchrony satisfied in all tests ");
  }
 
  protected int getRandomDelayInSeconds(int from,int to)
  {
    return from + r.nextInt(to-from);
  }



 
  private static class GroupMemberThread extends Thread {
    JChannel ch = null;
    int numberOfMessagesInView = 0;
    View currentView;
    View prevView;
    List payloads;
    VSynchPayload payload;
    volatile boolean running = true;
    Random r;
    int messagesSentPerView = 0;

    public GroupMemberThread(String name) {
      super(name);     
      payloads = new ArrayList();
      r = new Random();
      messagesSentPerView = r.nextInt(25);
    }

    public String getAddress() {
      if(ch!=null && ch.isConnected())
      {
        return ch.getAddress().toString();
      }
      else
      {
        return "disconnected " + getName();
      }
    }

    public void setRunning(boolean b) {
      running=b;
      System.out.println("Disconnect " + getAddress());
      if(ch!=null)ch.close();
    }

    public void run() {
      try {
        ch = new JChannel(CHANNEL_PROPS);
        ch.connect("vsynchtest");
      } catch (Exception e) {
        e.printStackTrace();
      }
     
      while (running) {
        Object msgReceived = null;
        try {
          msgReceived = ch.receive(0);
          if (!running) {
            // I am not a group member anymore so
            // I will discard any transient message I
            // receive
          } else {
            if (msgReceived instanceof View) {
              gotView(msgReceived);
            }

            if (msgReceived instanceof Message) {
              gotMessage(msgReceived);
            }
                       
                        if (msgReceived instanceof BlockEvent){
                           ch.blockOk();
                        }
          }

        } catch (TimeoutException e) {
        } catch (Exception e) {
          ch.close();
          running = false;
        }     
      }         
    }

    private void gotMessage(Object msgReceived) {
      Message msg = (Message) msgReceived;
      Object m = msg.getObject();

      if (m instanceof VSynchPayload) {
        VSynchPayload pay = (VSynchPayload) m;
        if (prevView != null && prevView.getVid().equals(pay.viewId)) {
          payloads.add(pay);
          boolean receivedAllPayloads = ((payloads.size() == prevView
              .getMembers().size()) || (payloads.size() == currentView
              .getMembers().size()));
          if (receivedAllPayloads) {                       
            VSynchPayload first=(VSynchPayload) payloads.get(0);
            for (Iterator i = payloads.listIterator(1); i.hasNext();) {
              VSynchPayload p = (VSynchPayload) i.next();
              assert first.msgViewCount == p.msgViewCount : "Member " + p + " and " + first + " failed VS";
            }
            System.out.println("VS ok, all " + payloads.size()
                + " members in " + prevView.getVid()
                + " view have received " + first.msgViewCount
                + " messages.\nAll messages sent in "
                + prevView.getVid() + " were delivered in "
                + prevView.getVid());
          }
        }
      } else if (m instanceof String) {
                assert currentView.getVid().getId() == Long.parseLong((String)m) : ch.getAddress()
                        + " received message from the wrong view. Message sender was " + msg.getSrc();
                numberOfMessagesInView++;
      }
    }

    private void gotView(Object msg) throws ChannelNotConnectedException, ChannelClosedException {
      View tmpView = (View) msg;     
      if (currentView != null) {
        payload = new VSynchPayload(currentView.getVid(),
            numberOfMessagesInView,ch.getAddress());
        ch.send(tmpView.getMembers().get(0), null, payload);
      }
      numberOfMessagesInView = 0;
      payloads.clear();
      prevView = currentView;
      currentView = tmpView;
      // send our allotment of messages
      for (int i = 0; i < messagesSentPerView; i++) {
        ch.send(null, null, Long.toString(currentView.getVid().getId()));
      }
    }
  }

  private static class VSynchPayload implements Serializable {
    public ViewId viewId;

    public int msgViewCount;

    public Address member;
        private static final long serialVersionUID=-3684761509882737012L;

        public VSynchPayload(ViewId viewId, int numbreOfMessagesInView,Address a) {
      super();
      this.viewId = viewId;
      this.msgViewCount = numbreOfMessagesInView;
      this.member=a;
    }

    public String toString() {
      return "[member=" +member + ",viewId=" + viewId.getId() + ",msgCount=" + msgViewCount
          + "]";
    }

  }
}
TOP

Related Classes of org.jgroups.tests.VirtualSynchronyTest$GroupMemberThread

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.