public ConnectToMessage(string contype, NodeInfo target, string token) { _ct = contype; _target_ni = target; _neighbors = new NodeInfo[0]; //Make sure this isn't null _token = token; }
public ConnectToMessage(string contype, NodeInfo target, NodeInfo[] neighbors, string token) { _ct = contype; _target_ni = target; _neighbors = neighbors; _token = token; }
public LinkMessage(StringDictionary attributes, NodeInfo local, NodeInfo remote, string token) { _attributes = attributes; _local_ni = local; _remote_ni = remote; _token = token; }
/** * @param t connection type * @param target the Address of the target node * @param token unique token used to associate all connection setup messages * with each other */ public ConnectToMessage(ConnectionType t, NodeInfo target, string token) { _ct = Connection.ConnectionTypeToString(t); _target_ni = target; _neighbors = new NodeInfo[0]; //Make sure this isn't null _token = token; }
public LinkMessage(string connection_type, NodeInfo local, NodeInfo remote, string token) { _attributes = new StringDictionary(); _attributes["type"] = String.Intern( connection_type ); _local_ni = local; _remote_ni = remote; _token = token; }
public LinkMessage(ConnectionType t, NodeInfo local, NodeInfo remote, string token) { _attributes = new StringDictionary(); _attributes["type"] = Connection.ConnectionTypeToString(t); _local_ni = local; _remote_ni = remote; _token = token; }
public ConnectToMessage(IDictionary ht) { _ct = (string)ht["type"]; _target_ni = NodeInfo.CreateInstance((IDictionary)ht["target"]); _token = (string) ht["token"]; IList neighht = ht["neighbors"] as IList; if( neighht != null ) { _neighbors = new NodeInfo[ neighht.Count ]; for(int i = 0; i < neighht.Count; i++) { _neighbors[i] = NodeInfo.CreateInstance( (IDictionary)neighht[i] ); } } }
public void CTMSerializationTest() { Address a = new DirectionalAddress(DirectionalAddress.Direction.Left); TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:5000"); NodeInfo ni = NodeInfo.CreateInstance(a, ta); RandomNumberGenerator rng = new RNGCryptoServiceProvider(); AHAddress tmp_add = new AHAddress(rng); ConnectToMessage ctm1 = new ConnectToMessage(ConnectionType.Unstructured, ni, tmp_add.ToString()); HTRoundTrip(ctm1); //Test multiple tas: ArrayList tas = new ArrayList(); tas.Add(ta); for(int i = 5001; i < 5010; i++) tas.Add(TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:" + i.ToString())); NodeInfo ni2 = NodeInfo.CreateInstance(a, tas); ConnectToMessage ctm2 = new ConnectToMessage(ConnectionType.Structured, ni2, tmp_add.ToString()); HTRoundTrip(ctm2); //Here is a ConnectTo message with a neighbor list: NodeInfo[] neighs = new NodeInfo[5]; for(int i = 0; i < 5; i++) { string ta_tmp = "brunet.tcp://127.0.0.1:" + (i+80).ToString(); NodeInfo tmp = NodeInfo.CreateInstance(new DirectionalAddress(DirectionalAddress.Direction.Left), TransportAddressFactory.CreateInstance(ta_tmp) ); neighs[i] = tmp; } ConnectToMessage ctm3 = new ConnectToMessage("structured", ni, neighs, tmp_add.ToString()); HTRoundTrip(ctm3); #if false Console.Error.WriteLine( ctm3.ToString() ); foreach(NodeInfo tni in ctm3a.Neighbors) { Console.Error.WriteLine(tni.ToString()); } #endif }
/** * This starts a linking operation on the given edge */ public IDictionary Start(IDictionary link_message, ISender edge) { if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -start- sys:link.Start", _node.Address)); } Edge from = GetEdge(edge); LinkMessage lm = new LinkMessage(link_message); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from)); } CphState cph = new CphState(from, lm); lock ( _sync ) { if (!_edge_to_cphstate.ContainsKey(from)) { _edge_to_cphstate[from] = cph; } else { throw new AdrException((int)ErrorMessage.ErrorCode.InProgress, "Already have a link in progress on this edge"); } } ErrorMessage err = null; if (CanConnect(cph, out err)) { try { //If the CloseEvent was already called, this throws an exception from.CloseEvent += this.CloseHandler; } catch { CloseHandler(from, null); throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed, "Edge Closed after receiving message"); } } else { lock ( _sync ) { _edge_to_cphstate.Remove(from); } } //Now we prepare our response LinkMessage lm_resp = null; if (err == null) { //We send a response: NodeInfo n_info = NodeInfo.CreateInstance(_node.Address, from.LocalTA); NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA); lm_resp = new LinkMessage(lm.ConTypeString, n_info, remote_info, _node.Realm, lm.Token); } else { if (err.Ec == ErrorMessage.ErrorCode.AlreadyConnected) { /** * When we send the ErrorCode.AlreadyConnected, * we could have a stale connection, lets try pinging * the other node, if they are there, but have lost * the Edge, this may trigger the edge to close, causing * us to remove the Connection. * @todo consider putting this address on a "fast track" * to removal if we don't hear from it soon */ ConnectionTable tab = _node.ConnectionTable; Connection c = tab.GetConnection(lm.ConnectionType, lm.Local.Address); if (c != null) { RpcManager rpc = _node.Rpc; rpc.Invoke(c.Edge, null, "sys:link.Ping", String.Empty); } } } if (err != null) { throw new AdrException((int)err.Ec, err.Message); } if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp)); } return(lm_resp.ToDictionary()); }
public void RoundTripHT(NodeInfo ni) { NodeInfo ni_other = NodeInfo.CreateInstance( ni.ToDictionary() ); Assert.AreEqual(ni, ni_other, "Hashtable roundtrip"); Assert.AreEqual(ni.GetHashCode(), ni_other.GetHashCode(), "Hashtable GetHashCode roundtrip"); }
public static NodeInfo CreateInstance(Address a, IList ta) { NodeInfo result = null; Cache ni_cache = Interlocked.Exchange<Cache>(ref _cache, null); if( ni_cache != null ) { try { //Set up the key: _cache_key._done_hash = false; _cache_key._address = a; _cache_key._tas = ta; result = (NodeInfo)ni_cache[_cache_key]; if( result == null ) { //This may look weird, but we are using a NodeInfo as a key //to lookup NodeInfos, this will allow us to only keep one //identical NodeInfo in scope at a time. result = new NodeInfo(a, ta); ni_cache[result] = result; } } finally { Interlocked.Exchange<Cache>(ref _cache, ni_cache); } } else { result = new NodeInfo(a, ta); } return result; }
static NodeInfo() { _cache = new WeakValueTable<int, NodeInfo>(); _cache_key = new NodeInfo(); _ta_list = new TransportAddress[1]; }
protected static NodeInfo CreateInstance(Address a, IList tas, TransportAddress ta) { NodeInfo result = null; var ni_cache = Interlocked.Exchange<WeakValueTable<int, NodeInfo>>(ref _cache, null); if(ni_cache != null) { try { //Set up the key: _cache_key._done_hash = false; _cache_key._address = a; if(tas == null) { if(ta == null) { _cache_key._tas = EmptyTas; } else { _ta_list[0] = ta; _cache_key._tas = _ta_list; } } else { _cache_key._tas = tas; } result = ni_cache.GetValue(_cache_key.GetHashCode()); if( !_cache_key.Equals(result) ) { //This may look weird, but we are using a NodeInfo as a key //to lookup NodeInfos, this will allow us to only keep one //identical NodeInfo in scope at a time. if(ta == null) { //Note, if ta == null that implies tas is not null result = new NodeInfo(a, tas); } else { result = new NodeInfo(a, ta); } ni_cache.Replace(result.GetHashCode(), result); } } finally { Interlocked.Exchange<WeakValueTable<int, NodeInfo>>(ref _cache, ni_cache); } } else if(ta == null) { //Note, if ta == null that implies tas is not null result = new NodeInfo(a, tas); } else { result = new NodeInfo(a, ta); } return result; }
public static NodeInfo CreateInstance(Address a, TransportAddress ta) { #if BRUNET_SIMULATOR return new NodeInfo(a, ta); #else NodeInfo result = null; Cache ni_cache = Interlocked.Exchange<Cache>(ref _cache, null); if( ni_cache != null ) { //Only one thread at the time can be in here: try { //Set up the key: _cache_key._done_hash = false; _cache_key._address = a; _ta_list[0] = ta; _cache_key._tas = _ta_list; result = (NodeInfo)ni_cache[_cache_key]; if( result == null ) { //This may look weird, but we are using a NodeInfo as a key //to lookup NodeInfos, this will allow us to only keep one //identical NodeInfo in scope at a time. result = new NodeInfo(a, ta); ni_cache[result] = result; } } finally { Interlocked.Exchange<Cache>(ref _cache, ni_cache); } } else { result = new NodeInfo(a, ta); } return result; #endif }
/** * This starts a linking operation on the given edge */ public IDictionary Start(IDictionary link_message, ISender edge) { if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -start- sys:link.Start", _node.Address)); } Edge from = GetEdge(edge); LinkMessage lm = new LinkMessage(link_message); if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from)); } CphState cph = new CphState(from, lm); lock ( _sync ) { if (!_edge_to_cphstate.ContainsKey(from)) { _edge_to_cphstate[from] = cph; } else { throw new AdrException((int)ErrorMessage.ErrorCode.InProgress, "Already have a link in progress on this edge"); } } ErrorMessage err = null; if (CanConnect(cph, out err)) { try { //If the CloseEvent was already called, this throws an exception from.CloseEvent += this.CloseHandler; } catch { CloseHandler(from, null); throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed, "Edge Closed after receiving message"); } } else { lock ( _sync ) { _edge_to_cphstate.Remove(from); } } //Now we prepare our response LinkMessage lm_resp = null; if (err == null) { //We send a response: NodeInfo n_info = NodeInfo.CreateInstance(_node.Address, from.LocalTA); NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA); lm_resp = new LinkMessage(lm.ConTypeString, n_info, remote_info, _node.Realm, lm.Token); } else { throw new AdrException((int)err.Ec, err.Message); } if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format( "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp)); } return(lm_resp.ToDictionary()); }
protected ConnectToMessage GetCtmResponseTo(ConnectToMessage ctm_req) { NodeInfo target = ctm_req.Target; //Send the 4 neighbors closest to this node: ArrayList nearest = _n.ConnectionTable.GetNearestTo( (AHAddress)target.Address, 4); //Now get these the NodeInfo objects for these: ArrayList neighbors = new ArrayList(); foreach(Connection cons in nearest) { //No need to send the TA, since only the address is used NodeInfo neigh = NodeInfo.CreateInstance(cons.Address); neighbors.Add( neigh ); } //Put these into an NodeInfo[] NodeInfo[] neigh_array = new NodeInfo[ neighbors.Count ]; for(int i = 0; i < neighbors.Count; i++) { neigh_array[i] = (NodeInfo)neighbors[i]; } return new ConnectToMessage(ctm_req.ConnectionType, _n.GetNodeInfo(12), neigh_array, ctm_req.Token); }
public void RoundTrip(NodeInfo ni) { NodeInfo ni_other = NodeInfo.CreateInstance(ni.Address, ni.Transports); Assert.AreEqual(ni, ni_other, "Hashtable roundtrip"); Assert.AreEqual(ni.GetHashCode(), ni_other.GetHashCode(), "Hashtable GetHashCode roundtrip"); }
/** * Factory method to reduce memory allocations by caching * commonly used NodeInfo objects */ public static NodeInfo CreateInstance(Address a) { //Read some of the least significant bytes out, //AHAddress all have last bit 0, so we skip the last byte which //will have less entropy MemBlock mb = a.ToMemBlock(); ushort idx = (ushort)NumberSerializer.ReadShort(mb, Address.MemSize - 3); NodeInfo ni = _mb_cache[idx]; if( ni != null ) { if (a.Equals(ni._address)) { return ni; } } ni = new NodeInfo(a); _mb_cache[idx] = ni; return ni; }
/// We want to include our 4 nearest neighbors override protected ConnectToMessage GetConnectToMessage(string ConnectionType, string token) { ArrayList nearest = _node.ConnectionTable.GetNearestTo( (AHAddress)_node.Address, 4); NodeInfo[] near_ni = new NodeInfo[nearest.Count]; int i = 0; foreach(Connection cons in nearest) { //We don't use the TAs, just the addresses near_ni[i] = NodeInfo.CreateInstance(cons.Address); i++; } return new ConnectToMessage(ConnectionType, _node.GetNodeInfo(12, TAAuth), near_ni, token); }
static NodeInfo() { _cache = new WeakValueTable <int, NodeInfo>(); _cache_key = new NodeInfo(); _ta_list = new TransportAddress[1]; }