Exemplo n.º 1
0
        /// <summary>
        /// Handles a refresh operation by requesting routing data from peers
        /// </summary>
        /// <returns>The refresh operation.</returns>
        /// <param name="selfinfo">The nodes own information.</param>
        /// <param name="request">Request.</param>
        /// <param name="k">The number of peers to request</param>
        public static async Task HandleRefreshOperation(PeerInfo selfinfo, PeerRequest request, int k)
        {
            var res = await VisitClosestPeers(selfinfo, request.Key ?? selfinfo.Key, request.Key == null?k : 1, 1, new Protocol.Request()
            {
                Self      = selfinfo,
                Operation = Protocol.Operation.FindPeer,
                Target    = selfinfo.Key
            });

            if (request.Response != null)
            {
                await request.Response.WriteAsync(new PeerResponse()
                {
                    SuccessCount = res.Count
                });
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Handles a request to add a value to the DHT
        /// </summary>
        /// <returns>The add operation.</returns>
        /// <param name="selfinfo">Selfinfo.</param>
        /// <param name="request">The request to handle.</param>
        /// <param name="k">The number of copies to store</param>
        public static async Task HandleAddOperation(PeerInfo selfinfo, PeerRequest request, int k)
        {
            var key = Key.ComputeKey(request.Data);

            log.Debug($"Handling the add request");
            var stored = await VisitClosestPeers(selfinfo, key, k, k, new Protocol.Request()
            {
                Self      = selfinfo,
                Operation = Protocol.Operation.Store,
                Data      = request.Data,
                Target    = key
            });

            await request.Response.WriteAsync(new PeerResponse()
            {
                SuccessCount = stored.Count
            });
        }
Exemplo n.º 3
0
        /// <summary>
        /// Handles the stats operation
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="request">The request to handle.</param>
        public static async Task HandleStatsOperation(PeerRequest request)
        {
            var brokerchan = Channel.Create <ConnectionStatsResponse>();
            var mruchan    = Channel.Create <MRUStatResponse>();
            var routechan  = Channel.Create <RoutingStatsResponse>();

            var brokertask = Task.Run(brokerchan.ReadAsync);
            var mrutask    = Task.Run(mruchan.ReadAsync);
            var routetask  = Task.Run(routechan.ReadAsync);

            // Send all requests
            await Task.WhenAll(
                Task.Run(() => Channels.ConnectionBrokerStats.Get().WriteAsync(brokerchan)),
                Task.Run(() => Channels.MRUStats.Get().WriteAsync(mruchan)),
                Task.Run(() => Channels.RoutingTableStats.Get().WriteAsync(routechan))
                );

            // Then wait for all results
            await Task.WhenAll(
                brokertask,
                mrutask,
                routetask
                );

            var sb = new StringBuilder();

            foreach (var n in new object[] { await brokertask, await mrutask, await routetask })
            {
                sb.AppendLine(string.Format("{0}:", n.GetType().Name));
                foreach (var p in n.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance))
                {
                    sb.AppendLine(string.Format("{0}: {1}", p.Name, p.GetValue(n)));
                }
            }

            await request.Response.WriteAsync(new PeerResponse()
            {
                Data = Encoding.UTF8.GetBytes(sb.ToString())
            });
        }
Exemplo n.º 4
0
        /// <summary>
        /// Handles the find operation
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="selfinfo">The nodes own information.</param>
        /// <param name="request">The request to handle.</param>
        /// <param name="k">The redundancy count</param>
        public static async Task HandleFindOperation(PeerInfo selfinfo, PeerRequest request, int k)
        {
            // Query the local value store first
            var data = await Channels.MRURequests.Get().SendGetAsync(request.Key);

            if (data != null)
            {
                log.Debug($"Local lookup for key succeeded");
                await request.Response.WriteAsync(new PeerResponse()
                {
                    Data         = data,
                    SuccessCount = 1
                });

                return;
            }

            var res = await VisitClosestPeers(selfinfo, request.Key, k, 1, new Protocol.Request()
            {
                Self      = selfinfo,
                Operation = Protocol.Operation.FindValue,
                Target    = request.Key
            });

            var result = res.Where(x => x.Success).FirstOrDefault();

            if (result.Success)
            {
                log.Debug($"Lookup succeeded for key, (re-)adding to local table");
                await Channels.MRURequests.Get().SendAddAsync(request.Key, result.Data);
            }

            await request.Response.WriteAsync(new PeerResponse()
            {
                Data         = result.Data,
                SuccessCount = res.Count
            });
        }