view src/fdl/test/debug/ConfigurationManagerEngine.java @ 97:0ea086f0e96f fuchita

main loop modification, for easy meta engine addition. add comments.
author one
date Wed, 26 May 2010 10:49:50 +0900
parents 9cdc24bae625
children
line wrap: on
line source

package fdl.test.debug;

import java.io.IOException;
import java.nio.ByteBuffer;

import fdl.*;

public class ConfigurationManagerEngine implements MetaEngine {
	public static final int DEFAULTPORT = 10000;

	// tuple id
	public static final int BODY = 100;
	public static final int START = 101;
	public static final int FINISH = 102;
	
	public static final int MANAGE = 60000;
	public static final int DEBUG = 61000;
	
	public static final int TREETOP = MANAGE + 1;
	public static final int TREELEFT = MANAGE + 2;
	public static final int TREERIGHT = MANAGE + 3;

	public static final int RINGLEFT = DEBUG + 1;
	public static final int RINGRIGHT = DEBUG + 2;
	
	public static final int DEBUGSTART = DEBUG + 1000;
	
	private int nodeNum = 0;
	private int relayNum = 0;
	private int relaySize = 1;
	private MetaLinda ml;
	private NodeInfo[] nodes;
	private boolean running = true;
	
	private class AcceptNewNode implements PSXCallback {
		int count = 0;
		public void callback(ByteBuffer reply) {
			String[] hostData = new String(reply.array()).split(":");
			String hostName = hostData[0];
			int	port = DEFAULTPORT;
			if (hostData.length > 1)
				port = new Integer(hostData[1]).intValue();
			nodes[count] = new NodeInfo(hostName, port);
			try {
				nodes[count].linda = ml.open(hostName, port);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (++count < nodeNum) {
				ml.in(MANAGE, this);
			} else {
				linkNodes();
				ml.in(MANAGE, new ConfirmConnectionNode());
			}
		}
	}
	
	private class ConfirmConnectionNode implements PSXCallback {
		int count = 0;
		public void callback(ByteBuffer reply) {
			if (++count < nodeNum) {
				ml.in(MANAGE, this);
			} else {
				routingNodes();
				ml.in(MANAGE, new ConfirmRoutingNode());
			}
		}

	}

	private class ConfirmRoutingNode implements PSXCallback {
		int count = 0;
		public void callback(ByteBuffer reply) {
			if (++count < nodeNum) {
				ml.in(MANAGE, this);
			} else {
				print("All link configured!");
				// TREE実験開始を通知
				// nodes[0].linda.out(START, ByteBuffer.wrap("test".getBytes()));
				// DebugRing 開始を通知
				nodes[0].linda.out(DEBUGSTART, ByteBuffer.wrap(("relay,"+new Integer(relayNum).toString()+","+new Integer(relaySize)).getBytes()));
				ml.in(MANAGE, new ConfirmFinish());
			}
		}

	}
	
	private class ConfirmFinish implements PSXCallback {
		public void callback(ByteBuffer reply) {
			System.out.println(new Integer(nodeNum).toString() + "," + new String(reply.array()));
			nodes[0].linda.out(DEBUGSTART, ByteBuffer.wrap("shutdown".getBytes()));
			print("Finish token");
			try {
				nodes[0].linda.sync(1);
			} catch (IOException e) {
				e.printStackTrace();
			}
			running = false;
		}

	}
	
	public ConfigurationManagerEngine(MetaLinda metaLinda, int nodeNum, int relayNum, int relaySize) {
		// initialize
		this.ml = metaLinda;
		this.nodeNum = nodeNum;
		this.relayNum = relayNum;
		this.relaySize = relaySize;
		nodes = new NodeInfo[nodeNum];
	}

	public void mainLoop(MetaLinda ml1) {
		// regist poll tuple id
		ml.in(MANAGE, new AcceptNewNode());
		while (running)
			ml.sync(0);
	}
	
	private void linkNodes() {
		for (int i = 0; i < nodes.length; i++) {
			// XML for Tree Topology
			ConnectionXMLBuilder tree = new ConnectionXMLBuilder(i);
			int k;
			if (i != 0) { // TOP
				k = (i-1)/2;
				tree.appendConnection(TREETOP, nodes[k].host, nodes[k].port, (i%2 == 0) ? TREERIGHT : TREELEFT);
			}
			if ((k = 2*i+1) < nodes.length) // LEFT
				tree.appendConnection(TREELEFT, nodes[k].host, nodes[k].port, TREETOP);
			if ((k = 2*i+2) < nodes.length) // RIGHT
				tree.appendConnection(TREERIGHT, nodes[k].host, nodes[k].port, TREETOP);
			nodes[i].connectionXML = tree.createXML();
			nodes[i].linda.out(MANAGE, ByteBuffer.wrap(nodes[i].connectionXML.getBytes()));
			print(nodes[i].connectionXML);
			
			// XML for Ring Debug Topology
			ConnectionXMLBuilder debug = new ConnectionXMLBuilder(i);
			int left = (nodes.length + i - 1) % nodes.length;
			int right = (i + 1) % nodes.length;
			debug.appendConnection(RINGLEFT, nodes[left].host, nodes[left].port, RINGRIGHT);
			debug.appendConnection(RINGRIGHT, nodes[right].host, nodes[right].port, RINGLEFT);
			nodes[i].debugConnectionXML = debug.createXML();
			nodes[i].linda.out(DEBUG, ByteBuffer.wrap(nodes[i].debugConnectionXML.getBytes()));
			print(nodes[i].debugConnectionXML);
		}
	}
	
	private void routingNodes() {
		for (int i = 0; i < nodes.length; i++) {
			RoutingXMLBuilder tree = new RoutingXMLBuilder();
			if (i != 0) { // TOP
				if (2*i+1 < nodes.length) { // LEFT
					tree.appendRoutingTable(TREETOP, TREELEFT);
					tree.appendRoutingTable(TREELEFT, TREETOP);
				}
				if (2*i+2 < nodes.length) { // RIGHT
					tree.appendRoutingTable(TREETOP, TREERIGHT);
					tree.appendRoutingTable(TREERIGHT, TREETOP);
				}
			}
			nodes[i].routingXML = tree.createXML();
			nodes[i].linda.out(MANAGE, ByteBuffer.wrap(nodes[i].routingXML.getBytes()));
			print(nodes[i].routingXML);
			
			RoutingXMLBuilder debug = new RoutingXMLBuilder();
			debug.appendRoutingTable(RINGLEFT, RINGRIGHT);
			debug.appendRoutingTable(RINGRIGHT, RINGLEFT);
			nodes[i].debugRoutingXML = debug.createXML();
			nodes[i].linda.out(DEBUG, ByteBuffer.wrap(nodes[i].debugRoutingXML.getBytes()));
			print(nodes[i].debugRoutingXML);
		}
	}
	
	void print(String str) {
		System.err.println("[DEBUG] ConfigurationManager: " + str);
	}
	
}