override protected void SeekTAs(DateTime now) { if (Interlocked.Exchange(ref _ongoing, 1) == 1) { return; } Channel chan = new Channel(); EventHandler handler = delegate(object o, EventArgs ea) { if (!chan.Closed && chan.Count < 8) { return; } List <TransportAddress> tas = new List <TransportAddress>(); while (chan.Count > 0) { AHAddress addr = null; try { IDictionary dict = (IDictionary)chan.Dequeue(); byte[] baddr = (byte[])dict["value"]; addr = new AHAddress(MemBlock.Reference(baddr)); } catch { continue; } tas.Add(new SubringTransportAddress(addr, _shared_namespace)); } if (tas.Count > 0) { CheckAndUpdateRemoteTAs(tas); } if (chan.Closed) { Interlocked.Exchange(ref _ongoing, 0); } }; if (_steady_state == 0) { chan.EnqueueEvent += handler; } chan.CloseEvent += handler; try { _dht.AsyncGet(_private_dht_key, chan); } catch (DhtException) { chan.Close(); } }
/// <summary>This is called if the cache's don't have an Address mapping. /// It prepares an asynchronous Dht query if one doesn't already exist, /// that is only one query at a time per IP regardless of how many misses /// occur. The ansychonorous call back is call MissCallback.</summary> /// <param name="ip">The IP Address to look up in the Dht.</param> protected bool Miss(MemBlock ip) { Channel queue = null; lock (_sync) { // Already looking up or found if (_queued.ContainsKey(ip)) { return(false); } int count = 1; if (_attempts.ContainsKey(ip)) { count = _attempts[ip] + 1; } _attempts[ip] = count; if (count >= 3) { _attempts.Remove(ip); throw new AddressResolutionException("No Address mapped to: " + Utils.MemBlockToString(ip, '.'), AddressResolutionException.Issues.DoesNotExist); } _queued[ip] = true; queue = new Channel(1); queue.CloseEvent += MissCallback; _mapping[queue] = ip; } String ips = Utils.MemBlockToString(ip, '.'); ProtocolLog.WriteIf(IpopLog.ResolverLog, String.Format("Adding {0} to queue.", ips)); byte[] key = Encoding.UTF8.GetBytes("dhcp:" + _ipop_namespace + ":" + ips); try { _dht.AsyncGet(key, queue); } catch { queue.CloseEvent -= MissCallback; lock (_sync) { _queued.Remove(ip); _mapping.Remove(queue); } queue.Close(); } return(true); }
public void HandleRpc(ISender caller, string method, IList args, object rs) { if (LocalUseOnly) { try { ReqrepManager.ReplyState _rs = (ReqrepManager.ReplyState)caller; Node node = (Node)_rs.ReturnPath; if (node != _node) { throw new Exception(); } } catch { AdrException e = new AdrException(-32602, new Exception("Must send from local node!")); _node.Rpc.SendResult(rs, e); return; } } object result = null; try { switch (method) { case "Create": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); MemBlock value = MemBlock.Reference((byte[])args[1]); int ttl = (int)args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncCreate(key, value, ttl, returns); return; } case "Put": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); MemBlock value = MemBlock.Reference((byte[])args[1]); int ttl = (int)args[2]; Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { _node.Rpc.SendResult(rs, returns.Dequeue()); }; _dht.AsyncPut(key, value, ttl, returns); return; } case "Get": { // Needs to be Async so we don't deadlock! MemBlock key = MemBlock.Reference((byte[])args[0]); Channel returns = new Channel(); returns.CloseEvent += delegate(object o, EventArgs eargs) { Hashtable [] results = new Hashtable[returns.Count]; int pos = 0; while (returns.Count > 0) { results[pos++] = (Hashtable)returns.Dequeue(); } _node.Rpc.SendResult(rs, results); }; _dht.AsyncGet(key, returns); return; } case "BeginGet": { MemBlock key = MemBlock.Reference((byte[])args[0]); result = BeginGet(key); break; } case "ContinueGet": { MemBlock token = MemBlock.Reference((byte[])args[0]); ContinueGet(token, rs); return; } case "EndGet": { MemBlock token = MemBlock.Reference((byte[])args[0]); EndGet(token); result = true; break; } } } catch (Exception e) { result = new AdrException(-32602, e); } _node.Rpc.SendResult(rs, result); }