/* * public Node findSuccessor(byte[] queryHashedKey, Node queryingNode) * { * if((Node)self<queryHashedKey && queryHashedKey<(Node)successor) * return successor; * else * { * Node closestPrecNode = findClosestPreceedingNode(queryHashedKey); * if (closestPrecNode==self) * return successor; * else * { * return closestPrecNode.findSuccessor(queryHashedKey, queryingNode); * } * } * } */ public void beginFindSuccessor(byte[] queryHashedKey, IChordNode queryingNode, AsyncCallback findSuccessorCallBack, Object appState, Guid relayTicket) { Console.WriteLine("Chord::engine::beginFindSuccessor ENTER"); ChordCommon.IChordNode_Object iNode_Object; lock (successorLock) { if ((ChordRealNode)self < queryHashedKey && queryHashedKey < (ChordRealNode)successor) { Console.WriteLine("Chord::engine::beginFindSuccessor query falls inbetween node and successor"); if (!(findSuccessorCallBack == null)) { iNode_Object = new ChordCommon.IChordNode_Object(); lock (successorLock) { iNode_Object.node = successor; } iNode_Object.obj = appState; IAsyncResult res = new ChordCommon.IChordNode_ObjectAsyncResult(iNode_Object, true, true); findSuccessorCallBack(res); } } else { Console.WriteLine("Chord::engine::beginFindSuccessor query DOES NOT fall inbetween node and successor"); IChordNode closestPrecNode = findClosestPreceedingNode(queryHashedKey); if (closestPrecNode == self) { Console.WriteLine("Chord::engine::beginFindSuccessor closestPrecNode==self"); if (!(findSuccessorCallBack == null)) { Console.WriteLine("Chord::engine::beginFindSuccessor if(!(findSuccessorCallBack==null))"); iNode_Object = new ChordCommon.IChordNode_Object(); lock (successorLock) { iNode_Object.node = successor; } iNode_Object.obj = appState; Console.WriteLine("Chord::engine::beginFindSuccessor before new IChordNode_ObjectAsyncResult"); IAsyncResult res = new ChordCommon.IChordNode_ObjectAsyncResult(iNode_Object, true, true); Console.WriteLine("Chord::engine::beginFindSuccessor before calling findSuccessorCallBack"); findSuccessorCallBack(res); } } else { Console.WriteLine("Chord::engine::beginFindSuccessor relaying request to closestPrecNode"); closestPrecNode.beginFindSuccessor(queryHashedKey, queryingNode, findSuccessorCallBack, appState, relayTicket); } } } Console.WriteLine("Chord::engine::beginFindSuccessor EXIT"); }
/* This is the method that the node uses to initilize its own state based on a supplied * bootstrap node here, it has been suppied with a bootstrap node which will be used to * initilize itself as well as tell other nodes in n/w of its existence * ALGO(from Chord TR): n.join(n′) * predecessor = nil; * s = n′.find successor(n); * build fingers(s); * successor = s; */ internal void beginJoin(IChordNode joinNode, AsyncCallback joinCallBack, Object appState) { Console.WriteLine("ChordRealNode::Engine::beginJoin ENTER"); predecessor = null; Tashjik.Common.AsyncCallback_Object thisAppState = new Tashjik.Common.AsyncCallback_Object(); thisAppState.callBack = joinCallBack; thisAppState.obj = appState; Console.WriteLine("ChordRealNode::Engine::beginJoin before calling beginFindSuccessor ahem ahem"); if (joinNode == null) { Console.WriteLine("ChordRealNode::Engine::beginJoin joinNode ==null"); } //queryingNode is passed as null, because it is of no use to beginFindSuccessor //if we were to pass 'self', then the system would hang. This is because Engine is part of //ChordRealNode. We haven't yet constructed ChordRealNode fully, and are in the process //of constructing Engine, and we want to send the partially constructed ChordRealNode // on a call to beginFindSuccessor // //What are the alternatives? //1. Make JoinNode as a public method tht needs to be called after construction of ChordRealNode //This may lead to maintainance issues of the calling code. What if at some later stage, someone //constructs the object, but forgets to call joinNode(..). This is typical of init(..) methods //which are supposed to be called by the user after constructor. Many a times, coders forget to do it. //2.Have a flag internal to ChordRealNode that will signal whether the object is ready for operation. //This would mean joinNode(..) has been called after construction. If this is not the case, throw an //excetion. This will easily be caught during basic testing. However, it may be a maintainance problem //for the maintainers of ChordRealNode itself> What if a new operation is added, and the engineer //forgets to check the flag before proceeding? // //We are fortunate here to have a hack (a nifty solution for me), that solves a larger design problem. joinNode.beginFindSuccessor(selfNodeBasic.getHashedIP(), null, new AsyncCallback(processFindSuccessorForJoin), thisAppState, new Guid("00000000-0000-0000-0000-000000000000")); }
/* This is the method that the node uses to initilize its own state based on a supplied * bootstrap node here, it has been suppied with a bootstrap node which will be used to * initilize itself as well as tell other nodes in n/w of its existence * ALGO(from Chord TR): n.join(n′) * predecessor = nil; * s = n′.find successor(n); * build fingers(s); * successor = s; */ internal void beginJoin(IChordNode joinNode, AsyncCallback joinCallBack, Object appState) { Console.WriteLine("ChordRealNode::Engine::beginJoin ENTER"); predecessor = null; Tashjik.Common.AsyncCallback_Object thisAppState = new Tashjik.Common.AsyncCallback_Object(); thisAppState.callBack = joinCallBack; thisAppState.obj = appState; Console.WriteLine("ChordRealNode::Engine::beginJoin before calling beginFindSuccessor ahem ahem"); if (joinNode == null) Console.WriteLine("ChordRealNode::Engine::beginJoin joinNode ==null"); //queryingNode is passed as null, because it is of no use to beginFindSuccessor //if we were to pass 'self', then the system would hang. This is because Engine is part of //ChordRealNode. We haven't yet constructed ChordRealNode fully, and are in the process //of constructing Engine, and we want to send the partially constructed ChordRealNode // on a call to beginFindSuccessor // //What are the alternatives? //1. Make JoinNode as a public method tht needs to be called after construction of ChordRealNode //This may lead to maintainance issues of the calling code. What if at some later stage, someone //constructs the object, but forgets to call joinNode(..). This is typical of init(..) methods //which are supposed to be called by the user after constructor. Many a times, coders forget to do it. //2.Have a flag internal to ChordRealNode that will signal whether the object is ready for operation. //This would mean joinNode(..) has been called after construction. If this is not the case, throw an //excetion. This will easily be caught during basic testing. However, it may be a maintainance problem //for the maintainers of ChordRealNode itself> What if a new operation is added, and the engineer //forgets to check the flag before proceeding? // //We are fortunate here to have a hack (a nifty solution for me), that solves a larger design problem. joinNode.beginFindSuccessor(selfNodeBasic.getHashedIP(), null, new AsyncCallback(processFindSuccessorForJoin), thisAppState, new Guid("00000000-0000-0000-0000-000000000000")); }