예제 #1
0
        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();
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
파일: RpcDht.cs 프로젝트: pcbing/brunet
        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);
        }