/** * Get a StatusMessage for this node */ public IDictionary GetStatus(IDictionary status_message, ISender edge) { //we just got s status request if( 1 == _disconnecting ) { throw new AdrException((int)ErrorMessage.ErrorCode.Disconnecting, "disconnecting"); } StatusMessage sm = new StatusMessage(status_message); Edge from = GetEdge(edge); if(ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -start- sys:link.GetStatus({1},{2})", _node.Address, sm, edge)); } CphState cphstate = null; if(from != null) { cphstate = _edge_to_cphstate[from] as CphState; } /** * StatusMessage objects are used to verify the completion * of the Link protocol. If we receive a StatusMessage request * after we send a LinkMessage response, we know the other * Node got our LinkMessage response, and the connection * is active */ StatusMessage response = null; ConnectionTable tab = _node.ConnectionTable; if (cphstate != null) { try { LinkMessage lm_to_add = cphstate.LM; //This is part of connection process: response = _node.GetStatus( sm.NeighborType, lm_to_add.Local.Address ); Connection con = new Connection(from, lm_to_add.Local.Address, lm_to_add.ConTypeString, sm, lm_to_add); tab.Add(con); } finally { from.CloseEvent -= this.CloseHandler; CloseHandler(from, null); } } else { //This is just a "regular" status request //update our table: Address fadd = null; Connection c = tab.GetConnection(from); if( c != null ) { fadd = c.Address; tab.UpdateStatus(c, sm); } response = _node.GetStatus( sm.NeighborType, fadd ); } if(ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -end- sys:link.GetStatus()->{1}", _node.Address,response)); } return response.ToDictionary(); }
/** * When the ConnectionTable changes, our cached routes are all trash */ protected void ConnectionTableChangeHandler(object o, System.EventArgs args) { Connection new_left = null; bool structs_changed = false; if( args != null ) { /* * This is sometimes called (in Route) with args set to null * when we need to clear the _route_cache. * So don't look at args if they are null. */ ConnectionEventArgs ce = (ConnectionEventArgs)args; ConnectionList cl = ce.CList; structs_changed = (cl.MainType == ConnectionType.Structured); if( structs_changed ) { if (cl.Count > 0) { /* * Compute our left neighbor. We only need to do this when it * has changed. */ int our_idx = cl.IndexOf(_local); if( our_idx < 0 ) { our_idx = ~our_idx; } else { Console.Error.WriteLine( "ERROR: we are in the ConnectionTable: {0}", _local); } new_left = cl[our_idx]; } else { //We have no neighbors: new_left = null; } } } lock( _sync ) { _route_cache.Clear(); if( structs_changed ) { _our_left_n = new_left; } } }
protected void StatusChangedHandler(object ct, System.EventArgs args) { ConnectionEventArgs ce = (ConnectionEventArgs)args; Connection new_con = ce.Connection; lock( _sync ) { if (_our_left_n != null) { if( new_con.Edge == _our_left_n.Edge ) { _our_left_n = new_con; } } } }
/** * When we're here, we have the status message */ protected void StatusCloseHandler(object q, EventArgs args) { try { Channel resq = (Channel)q; //If we got no result RpcResult res = (RpcResult)resq.Dequeue(); StatusMessage sm = new StatusMessage((IDictionary)res.Result); if(_node.EdgeVerifyMethod != null) { if(!_node.EdgeVerifyMethod(_node, _e, LinkMessageReply.Local.Address)) { throw new Exception("Edge verification failed!"); } } Connection c = new Connection(_e, LinkMessageReply.Local.Address, _contype, sm, LinkMessageReply); _node.ConnectionTable.Add(c); _con.Value = c; Finish(Result.Success); } catch(InvalidOperationException) { /* * This is unexpected. */ string message = String.Format( "No StatusMessage returned from open({1}) Edge: {0}", _e, !_e.IsClosed); if(ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, message); } /* * We got a link message from this guy, but not a status response, * so let's try this TA again. */ Finish(Result.RetryThisTA); } catch(Exception x) { /* * Clearly we got some response from this edge, but something * unexpected happened. Let's try it this edge again if we * can */ if(ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "LPS.StatusResultHandler Exception: {0}", x)); } Finish(Result.RetryThisTA); } }
public CachedRoute(Connection route, bool send_local) { Route = route; DeliverLocally = send_local; }
public ConnectionEventArgs(Connection c, int idx, ConnectionList cl, int view) { Connection = c; Index = idx; CList = cl; View = view; }
/** * Call the GetStatus method on the given connection */ protected void CallGetStatus(string type, Connection c) { ConnectionTable tab = this.ConnectionTable; if( c != null ) { StatusMessage req = GetStatus(type, c.Address); Channel stat_res = new Channel(1); EventHandler handle_result = delegate(object q, EventArgs eargs) { try { RpcResult r = (RpcResult)stat_res.Dequeue(); StatusMessage sm = new StatusMessage( (IDictionary)r.Result ); tab.UpdateStatus(c, sm); } catch(Exception) { //Looks like lc disappeared before we could update it } }; stat_res.CloseEvent += handle_result; RpcManager rpc = RpcManager.GetInstance(this); rpc.Invoke(c.Edge, stat_res, "sys:link.GetStatus", req.ToDictionary() ); } }
public AnnealingRouting(AHAddress local, ConnectionList structured_cons) { //Fake connection to ourselves: _local_con = new Connection(null, local, "structured.self", null, null); int local_idx; _structs = ConnectionList.InsertInto(structured_cons, _local_con, out local_idx); }
public GreedyRouting(AHAddress local, ConnectionList structured_cons) { //Fake connection to ourselves: _local_con = new Connection(null, local, "structured.self", null, null); int local_idx; _structs = ConnectionList.InsertInto(structured_cons, _local_con, out local_idx); _NO_ONE = new Pair<Connection, bool>(null, false); _LOCAL = new Pair<Connection, bool>(null, true); }
/** <summary>Begins a new transfer state to the neighbor connected via con. </summary> <param name="con">The connection to the neigbhor we will be transferring data to.</param> <param name="ts">The table server we're providing the transfer for. C# does not allow sub-class objects to have access to their parent objects member variables, so we pass it in like this.</param> <remarks> Step 1: Get all the keys between me and my new neighbor. Step 2: Get all values for those keys, we copy so that we don't worry about changes to the dht during this interaction. This is only a pointer copy and since we let the OS deal with removing the contents of an entry, we don't need to make copies of the actual entry. Step 3: Generate another list of keys of up to max parallel transfers and begin transferring, that way we do not need to lock access to the entry enumerator until non-constructor puts. Step 4: End constructor, results from puts, cause the next entry to be sent. */ public TransferState(Connection con, TableServer ts) { this._ts = ts; this._con = con; // Get all keys between me and my new neighbor LinkedList<MemBlock> keys; lock(_ts._sync) { keys = _ts._data.GetKeysBetween((AHAddress) _ts._node.Address, (AHAddress) _con.Address); } if(Dht.DhtLog.Enabled) { ProtocolLog.Write(Dht.DhtLog, String.Format( "Starting transfer from {0} to {1}", _ts._node.Address, _con.Address)); } int total_entries = 0; /* Get all values for those keys, we copy so that we don't worry about * changes to the dht during this interaction. This is only a pointer * copy and since we let the OS deal with removing the contents of an * entry, we don't need to make copies of the actual entry. */ foreach(MemBlock key in keys) { Entry[] entries; lock(_ts._sync) { LinkedList<Entry> llentries = _ts._data.GetEntries(key); if(llentries == null) { continue; } entries = new Entry[llentries.Count]; total_entries += llentries.Count; llentries.CopyTo(entries, 0); } key_entries.AddLast(entries); } if(Dht.DhtLog.Enabled) { ProtocolLog.Write(Dht.DhtLog, String.Format( "Total keys: {0}, total entries: {1}.", key_entries.Count, total_entries)); } _entry_enumerator = GetEntryEnumerator(); /* Here we generate another list of keys that we would like to * this is done here, so that we can lock up the _entry_enumerator * only during this stage and not during the RpcManager.Invoke */ LinkedList<Entry> local_entries = new LinkedList<Entry>(); for(int i = 0; i < MAX_PARALLEL_TRANSFERS && _entry_enumerator.MoveNext(); i++) { local_entries.AddLast((Entry) _entry_enumerator.Current); } foreach(Entry ent in local_entries) { Channel queue = new Channel(); queue.CloseAfterEnqueue(); queue.CloseEvent += this.NextTransfer; int ttl = (int) (ent.EndTime - DateTime.UtcNow).TotalSeconds; try { _ts._rpc.Invoke(_con.Edge, queue, "dht.PutHandler", ent.Key, ent.Value, ttl, false); } catch { if(_con.Edge.IsClosed) { _interrupted = true; Done(); break; } } } }