Limit SourceServerQuery to one concurrent request per endpoint

This commit is contained in:
Rohan Singh 2019-12-07 08:41:06 -05:00
parent 2e6db5fe37
commit 710c6a0ce7
8 changed files with 45 additions and 18 deletions

View File

@ -15,26 +15,53 @@ internal static class SourceServerQuery
// private static readonly byte A2S_PLAYER = 0x55;
private static readonly byte A2S_RULES = 0x56;
internal static async Task<Dictionary<string, string>> GetRules( ServerInfo server )
{
try
{
var endpoint = new IPEndPoint( server.Address, server.QueryPort );
private static readonly Dictionary<IPEndPoint, Task<Dictionary<string, string>>> PendingQueries =
new Dictionary<IPEndPoint, Task<Dictionary<string, string>>>();
using ( var client = new UdpClient() )
{
client.Client.SendTimeout = 3000;
client.Client.ReceiveTimeout = 3000;
client.Connect( endpoint );
internal static Task<Dictionary<string, string>> GetRules( ServerInfo server )
{
var endpoint = new IPEndPoint(server.Address, server.QueryPort);
return await GetRules( client );
}
}
catch ( System.Exception e )
{
//Console.Error.WriteLine( e.Message );
return null;
}
lock (PendingQueries)
{
if (PendingQueries.TryGetValue(endpoint, out var pending))
return pending;
var task = GetRulesImpl(endpoint, server)
.ContinueWith(t =>
{
lock (PendingQueries)
{
PendingQueries.Remove(endpoint);
}
return t;
})
.Unwrap();
PendingQueries.Add(endpoint, task);
return task;
}
}
private static async Task<Dictionary<string, string>> GetRulesImpl( IPEndPoint endpoint, ServerInfo server )
{
try
{
using (var client = new UdpClient())
{
client.Client.SendTimeout = 3000;
client.Client.ReceiveTimeout = 3000;
client.Connect(endpoint);
return await GetRules(client);
}
}
catch (System.Exception e)
{
//Console.Error.WriteLine( e.Message );
return null;
}
}
static async Task<Dictionary<string, string>> GetRules( UdpClient client )