auto-restart on fatal http error
This commit is contained in:
@@ -13,7 +13,9 @@ public class ApiServer(string apiUrl) : IApiServer
|
||||
{
|
||||
protected readonly List<PrivateMessageHandler> handlers = [];
|
||||
protected readonly Dictionary<Type, IApiMessageSerializer> serializers = [];
|
||||
protected readonly HttpListener httpListener = new();
|
||||
protected HttpListener httpListener = new();
|
||||
protected int restartAttempts = 0;
|
||||
protected DateTime lastRestartAttempt;
|
||||
|
||||
public event OnCheckAuthenticationEventHandler? OnCheckAuthentication;
|
||||
public event OnCheckContextEventHandler? OnCheckContext;
|
||||
@@ -37,18 +39,48 @@ public class ApiServer(string apiUrl) : IApiServer
|
||||
|
||||
public bool AllowMultipleRequests { get; set; }
|
||||
|
||||
public int StopDelay { get; set; } = 5000;
|
||||
|
||||
public int AutoRestartOnError { get; set; } = 5000;
|
||||
|
||||
public int MaxAutoRestartsPerMinute { get; set; } = 10;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
Log.Info("Start listening");
|
||||
Log.Info("Starting listener");
|
||||
httpListener.Prefixes.Add(ApiUrl + "/");
|
||||
httpListener.Start();
|
||||
Log.Info("Started listener");
|
||||
Receive();
|
||||
}
|
||||
|
||||
public virtual void Stop()
|
||||
{
|
||||
Log.Info("Stopping listener");
|
||||
httpListener.Stop();
|
||||
Log.Info("Stopped listening");
|
||||
Thread.Sleep(StopDelay);
|
||||
httpListener.Close();
|
||||
Log.Info("Stopped listener");
|
||||
}
|
||||
|
||||
public virtual bool Restart()
|
||||
{
|
||||
if (restartAttempts > MaxAutoRestartsPerMinute)
|
||||
return false;
|
||||
|
||||
var now = DateTime.Now;
|
||||
if (now - lastRestartAttempt > TimeSpan.FromMinutes(1))
|
||||
lastRestartAttempt = now;
|
||||
|
||||
restartAttempts += 1;
|
||||
|
||||
Log.Info("Restarting listener");
|
||||
Stop();
|
||||
httpListener = new();
|
||||
Start();
|
||||
Log.Info("Restarted listener");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void RegisterHandler<T>(T instance) where T : class
|
||||
@@ -130,6 +162,18 @@ public class ApiServer(string apiUrl) : IApiServer
|
||||
{
|
||||
context = httpListener.EndGetContext(result);
|
||||
}
|
||||
catch (HttpListenerException ex)
|
||||
{
|
||||
if (ex.ErrorCode == 995 || ex.ErrorCode == 64)
|
||||
{
|
||||
Log.Fatal($"Fatal http error retriving context with code {ex.ErrorCode}", ex);
|
||||
if (Restart()) // Try restart the server and skip this context
|
||||
return;
|
||||
}
|
||||
else
|
||||
Log.Error($"Http error retriving context with code {ex.ErrorCode}", ex);
|
||||
context = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error retriving context", ex);
|
||||
@@ -251,11 +295,13 @@ public class ApiServer(string apiUrl) : IApiServer
|
||||
context.Response.ContentType = "application/json";
|
||||
using StreamWriter output = new(context.Response.OutputStream);
|
||||
output.Write(resultJson);
|
||||
output.Flush();
|
||||
}
|
||||
else if (result.ResultContent is byte[] resultBytes)
|
||||
{
|
||||
Log.Info("Sending raw bytes response for " + context.Request.RawUrl);
|
||||
context.Response.OutputStream.Write(resultBytes, 0, resultBytes.Length);
|
||||
context.Response.OutputStream.Flush();
|
||||
}
|
||||
|
||||
Log.Debug("Finish response");
|
||||
|
||||
Reference in New Issue
Block a user