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