use SemaphoreSlim to limit the amount of parallel http requests
This commit is contained in:
@@ -16,6 +16,7 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
protected HttpListener httpListener = new();
|
protected HttpListener httpListener = new();
|
||||||
protected int restartAttempts = 0;
|
protected int restartAttempts = 0;
|
||||||
protected DateTime lastRestartAttempt;
|
protected DateTime lastRestartAttempt;
|
||||||
|
protected SemaphoreSlim? semaphore;
|
||||||
|
|
||||||
public event OnCheckAuthenticationEventHandler? OnCheckAuthentication;
|
public event OnCheckAuthenticationEventHandler? OnCheckAuthentication;
|
||||||
public event OnCheckContextEventHandler? OnCheckContext;
|
public event OnCheckContextEventHandler? OnCheckContext;
|
||||||
@@ -45,6 +46,8 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
|
|
||||||
public int MaxAutoRestartsPerMinute { get; set; } = 10;
|
public int MaxAutoRestartsPerMinute { get; set; } = 10;
|
||||||
|
|
||||||
|
public int MaxConcurentConnections { get; set; } = 5;
|
||||||
|
|
||||||
public virtual void Start()
|
public virtual void Start()
|
||||||
{
|
{
|
||||||
Log.Info("Starting listener");
|
Log.Info("Starting listener");
|
||||||
@@ -68,6 +71,7 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
Log.Info("Restarting listener");
|
Log.Info("Restarting listener");
|
||||||
Stop();
|
Stop();
|
||||||
httpListener = new();
|
httpListener = new();
|
||||||
|
semaphore?.Release(int.MaxValue);
|
||||||
Start();
|
Start();
|
||||||
Log.Info("Restarted listener");
|
Log.Info("Restarted listener");
|
||||||
}
|
}
|
||||||
@@ -92,6 +96,17 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void WaitForSlot()
|
||||||
|
{
|
||||||
|
semaphore ??= new(MaxConcurentConnections);
|
||||||
|
semaphore.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void FreeSlot()
|
||||||
|
{
|
||||||
|
semaphore?.Release();
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void RegisterHandler<T>(T instance) where T : class
|
public virtual void RegisterHandler<T>(T instance) where T : class
|
||||||
{
|
{
|
||||||
// Get all public instance methods
|
// Get all public instance methods
|
||||||
@@ -166,6 +181,18 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
if (!httpListener.IsListening)
|
if (!httpListener.IsListening)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Wait for a free slot
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WaitForSlot();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Fatal($"Too many concurent connections", ex);
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get context
|
// Get context
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -195,7 +222,10 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
|
|
||||||
// Cancel if we don't have a context
|
// Cancel if we don't have a context
|
||||||
if (context is null)
|
if (context is null)
|
||||||
|
{
|
||||||
|
FreeSlot();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check context
|
// Check context
|
||||||
Log.Info("Request retrived for " + context.Request.RawUrl);
|
Log.Info("Request retrived for " + context.Request.RawUrl);
|
||||||
@@ -215,6 +245,9 @@ public class ApiServer(string apiUrl) : IApiServer
|
|||||||
OnCheckContextCompleted?.Invoke(this, new(context));
|
OnCheckContextCompleted?.Invoke(this, new(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release slot
|
||||||
|
FreeSlot();
|
||||||
|
|
||||||
// Listen for new request
|
// Listen for new request
|
||||||
if (!AllowMultipleRequests)
|
if (!AllowMultipleRequests)
|
||||||
Receive();
|
Receive();
|
||||||
|
|||||||
Reference in New Issue
Block a user