|
From: Jonathan L. <le...@us...> - 2006-11-27 15:34:44
|
Update of /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/nc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3699/src/edu/harvard/syrah/pyxida/nc Modified Files: NCManager.java Log Message: starting to test Index: NCManager.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/nc/NCManager.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** NCManager.java 27 Nov 2006 11:10:48 -0000 1.5 --- NCManager.java 27 Nov 2006 15:34:40 -0000 1.6 *************** *** 1,11 **** ! package edu.harvard.syrah.pyxida.nc; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; import edu.harvard.syrah.prp.Log; import edu.harvard.syrah.pyxida.nc.lib.Coordinate; import edu.harvard.syrah.pyxida.nc.lib.NCClient; import edu.harvard.syrah.pyxida.ping.PingManager; --- 1,14 ---- ! package edu.harvard.syrah.pyxida.nc; import java.util.Arrays; import java.util.HashSet; + import java.util.ArrayList; import java.util.Map; + import java.util.HashMap; import java.util.Set; import edu.harvard.syrah.prp.Log; import edu.harvard.syrah.pyxida.nc.lib.Coordinate; + import edu.harvard.syrah.pyxida.*; import edu.harvard.syrah.pyxida.nc.lib.NCClient; import edu.harvard.syrah.pyxida.ping.PingManager; *************** *** 22,27 **** import edu.harvard.syrah.sbon.comm.obj.ObjMessageIF; ! // TODO add proxy coordinates public class NCManager { private static final Log log = new Log(NCManager.class); --- 25,36 ---- import edu.harvard.syrah.sbon.comm.obj.ObjMessageIF; ! // MEDTODO add proxy coordinates + /** + * Manages the local and proxy coordinates. + * Initiates gossip to other overlay nodes. + * Receives and responds to gossip messages. + * Manages gossip set, e.g. set of overlay nodes that the coordinates might use as neighbors + */ public class NCManager { private static final Log log = new Log(NCManager.class); *************** *** 36,44 **** // which is important for Azureus integration. ! // TODO JTL: You need to test the regex below. It should work private String bootstrapList[] = Config.getProperty("pyxida.bootstraplist", "glenora, sb01, sb02, sb10, sb11").split("[,\\s]"); - - public static final long UPDATE_DELAY = 10 * 1000; // 10 seconds public static final long DEFAULT_PROXY_LEASE = 3600 * 1000; --- 45,61 ---- // which is important for Azureus integration. ! // JTLTODO: You need to test the regex below. It should work private String bootstrapList[] = Config.getProperty("pyxida.bootstraplist", "glenora, sb01, sb02, sb10, sb11").split("[,\\s]"); + /** + * Time between gossip messages to coordinate neighbors. + * Default is 10 seconds. + */ + public static final long UPDATE_DELAY = 10 * 1000; + + /** + * Default lifetime that proxy coordinates are managed for. + * Set to one hour. + */ public static final long DEFAULT_PROXY_LEASE = 3600 * 1000; *************** *** 50,53 **** --- 67,77 ---- final CoordClient localNC; + Map<AddressIF,Long> neighbor2age; + ArrayList<AddressIF> neighbors; + + /** + * Create a coordinate manager. + * Does not block. + */ public NCManager(ObjCommIF _comm, PingManager pingManager) { comm = _comm; *************** *** 57,63 **** --- 81,95 ---- } + /** + * Asynchronous initialization of coordinate manager. + * Resolves bootstrap neighbors and starts gossip for local coordinate. + * Starts listening for gossip messages. + */ public void init(final CB0 cbDone) { comm.registerMessageCB(GossipRequestMsg.class, new GossipHandler()); + neighbor2age = new HashMap<AddressIF,Long>(); + neighbors = new ArrayList<AddressIF>(); + AddressFactory.createResolved(Arrays.asList(bootstrapList), new CB1<Map<String, AddressIF>>() { protected void cb(CBResult result, Map<String, AddressIF> addrMap) { *************** *** 66,75 **** for (String remoteNode : addrMap.keySet()) { AddressIF remoteAddr = addrMap.get(remoteNode); ! // TODO JTL: add remoteAddr to your data structure } localNC.init(); ! // Also ping for any proxy coordinates. cbDone.callOK(); --- 98,109 ---- for (String remoteNode : addrMap.keySet()) { AddressIF remoteAddr = addrMap.get(remoteNode); ! addGossipNode(remoteAddr); } + // Starts local coordinate timer localNC.init(); ! // MEDTODO Start periodic cleaner ! //neighborClean(); cbDone.callOK(); *************** *** 86,110 **** } public void createProxyCoord(AddressIF remoteNode, long lease) { ! // TODO } public void destroyProxyCoord(AddressIF remoteNode) { ! // TODO } public Coordinate getLocalCoord() { return localNC.nc.getSystemCoords(); } public double getLocalError() { return localNC.nc.getSystemError(); } public Coordinate getProxyCoord(AddressIF remoteNode) { ! // TODO return null; } public double estimateRTT(AddressIF nodeA, AddressIF nodeB) { // TODO --- 120,162 ---- } + /** + * Not implemented yet. + */ public void createProxyCoord(AddressIF remoteNode, long lease) { ! // LOWTODO } + /** + * Not implemented yet. + */ public void destroyProxyCoord(AddressIF remoteNode) { ! // LOWTODO } + /** + * @return local coordinate + */ public Coordinate getLocalCoord() { return localNC.nc.getSystemCoords(); } + /** + * @return local error + */ public double getLocalError() { return localNC.nc.getSystemError(); } + /** + * Not implemented yet. + */ public Coordinate getProxyCoord(AddressIF remoteNode) { ! // LOWTODO return null; } + /** + * + */ public double estimateRTT(AddressIF nodeA, AddressIF nodeB) { // TODO *************** *** 113,123 **** /* ! // TODO PRP low priority public void startUp(DataInputStream is) throws IOException { - // TODO } public void shutDown(DataOutputStream os) throws IOException { - // TODO } */ --- 165,173 ---- /* ! // LOWTODO PRP public void startUp(DataInputStream is) throws IOException { } public void shutDown(DataOutputStream os) throws IOException { } */ *************** *** 168,213 **** } Set<AddressIF> getGossipNodes(Coordinate remoteCoord) { ! // TODO return coordinates, possibly based on this guy's coordinate ! return null; } void addGossipNodes(Set<AddressIF> nodes) { ! // TODO add nodes to the set that we know about } ! AddressIF getGossipNode() { ! // TODO return a guy to gossip with ! return null; } class CoordClient { final NCClient<AddressIF> nc; public CoordClient() { nc = new NCClient<AddressIF>(NCManager.NC_NUM_DIMS); } public void init() { ! // TODO continuous timer ! // really would prefer randomly distributed timings ! // or an adaptive delay :) ! // ! // TODO JTL ! // ! // You can easily do this by varying UPDATE_DELAY. Remember that the semantics ! // of the call is that you have to re-register after each callback. ! EventLoop.get().registerTimerCB(UPDATE_DELAY, new CB0() { ! protected void cb(CBResult result) { ! update(); ! } ! }); } void update() { final AddressIF neighbor = pickGossipNode(); // send him a gossip msg ! // TODO could bias which nodes are sent based on his coord GossipRequestMsg msg = new GossipRequestMsg(localNC.nc.getSystemCoords(), getGossipNodes(null)); --- 218,302 ---- } + + AddressIF getGossipNode() { + if (neighbors.size() == 0) { + log.warn("we are lonely and have no one to gossip with"); + return null; + } + + int index = Pyxida.random.nextInt(neighbors.size()); + AddressIF node = neighbors.get(index); + + return node; + } + Set<AddressIF> getGossipNodes(Coordinate remoteCoord) { ! Set<AddressIF> nodes = new HashSet<AddressIF>(); ! // LOWTODO add option of loop here ! AddressIF node = getGossipNode(); ! if (node != null) { ! nodes.add(node); ! } ! return nodes; } void addGossipNodes(Set<AddressIF> nodes) { ! for (AddressIF node : nodes) { ! addGossipNode (node); ! } } ! void addGossipNode(AddressIF node) { ! long curr_time = System.currentTimeMillis(); ! Long expiry = neighbor2age.get(node); ! if (expiry != null) { ! log.debug ("gossip already knew node "+node); ! long old_time = expiry.longValue(); ! expiry = new Long (curr_time); ! ! expiry = neighbor2age.get(node); ! long new_time = expiry.longValue(); ! log.debug ("old_time "+old_time+" new "+new_time); ! ! return; ! } ! neighbors.add(node); ! neighbor2age.put(node,curr_time); ! log.debug ("gossip added new neighbor "+node); } class CoordClient { final NCClient<AddressIF> nc; + final CB0 updateCB; public CoordClient() { nc = new NCClient<AddressIF>(NCManager.NC_NUM_DIMS); + + updateCB = new CB0() { + protected void cb(CBResult result) { + update(); + } + }; + } + void registerTimer () { + // LOWTODO adaptive delay + double rnd = Pyxida.random.nextGaussian(); + long delay = UPDATE_DELAY + (long)(1000 * rnd); + log.debug ("setting timer to "+delay); + EventLoop.get().registerTimerCB(delay, updateCB); + } + public void init() { ! registerTimer(); } void update() { + registerTimer(); final AddressIF neighbor = pickGossipNode(); // send him a gossip msg ! // LOWTODO could bias which nodes are sent based on his coord GossipRequestMsg msg = new GossipRequestMsg(localNC.nc.getSystemCoords(), getGossipNodes(null)); *************** *** 217,225 **** AddressIF remoteAddr, Long ts, CB1<Boolean> cbHandled) { ! // TODO can use time of this instead of ping time // if we want to not use jpcap pings // (running not at root) // ! // TODO JTL: good idea. however, i'm not sure what the best way is to integrate this... // Ideally, all latency measurements should be done by the ping manager...? --- 306,314 ---- AddressIF remoteAddr, Long ts, CB1<Boolean> cbHandled) { ! // LOWTODO can use time of this instead of ping time // if we want to not use jpcap pings // (running not at root) // ! // However however PRP not sure what the best way is to integrate this... // Ideally, all latency measurements should be done by the ping manager...? *************** *** 234,246 **** switch (pingResult.state) { case OK: { - // and update our coordinate ! // TODO convert nclib to use floats // ! // TODO JTL: why do you want to use floats and not double? won't we run into // accuracy problems? long lat_ms = (long) Math.round(latency); long curr_time = System.currentTimeMillis(); localNC.nc.processSample(neighbor, responseMsg.remoteCoordinate, responseMsg.remoteError, lat_ms, responseMsg.remoteAge, curr_time, true); --- 323,336 ---- switch (pingResult.state) { case OK: { ! ! // MEDTODO convert nclib to use floats // ! // JTLTODO: why do you want to use floats and not double? won't we run into // accuracy problems? long lat_ms = (long) Math.round(latency); long curr_time = System.currentTimeMillis(); + // and update our coordinate localNC.nc.processSample(neighbor, responseMsg.remoteCoordinate, responseMsg.remoteError, lat_ms, responseMsg.remoteAge, curr_time, true); *************** *** 270,274 **** AddressIF pickGossipNode() { ! // TODO ask our ncClient if it has a preferred gossip node // if not, use somebody from our neighbor set --- 360,364 ---- AddressIF pickGossipNode() { ! // LOWTODO ask our ncClient if it has a preferred gossip node // if not, use somebody from our neighbor set *************** *** 284,288 **** void update() { ! AddressIF neighbor = pickGossipNode(); // ask him to ping our address --- 374,379 ---- void update() { ! registerTimer(); ! final AddressIF neighbor = pickGossipNode(); // ask him to ping our address *************** *** 296,300 **** super(); renewLease(_lease); ! // TODO Does this need to be cloned? // prp: Don't know but if you want to clone it, use the copy constructor addr = AddressFactory.create(_addr); --- 387,391 ---- super(); renewLease(_lease); ! // MEDTODO Does this need to be cloned? // prp: Don't know but if you want to clone it, use the copy constructor addr = AddressFactory.create(_addr); |