/// <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 }); } }
/// <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 }); }
/// <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()) }); }
/// <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 }); }