add some default types to de-duplicate similar implmentations

This commit is contained in:
Pilzinsel64
2025-03-28 10:40:48 +01:00
parent 9a652a343c
commit 8de643b7d1
17 changed files with 555 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
using Castle.Core.Logging;
using Pilz.Extensions.Reflection;
using Pilz.Net.Data;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Reflection;
@@ -12,8 +13,12 @@ namespace Pilz.Net.Api;
public class ApiServer : IApiServer
{
protected record struct ThreadHolder(Thread? Thread);
public class MissingDataManagerException : Exception { }
protected readonly List<PrivateMessageHandler> handlers = [];
protected readonly Dictionary<Type, IApiMessageSerializer> serializers = [];
protected readonly Dictionary<ThreadHolder, IDataManager> managers = [];
protected HttpListener httpListener;
protected int restartAttempts = 0;
protected DateTime lastRestartAttempt;
@@ -24,6 +29,8 @@ public class ApiServer : IApiServer
public event OnCheckAuthenticationEventHandler? OnCheckAuthentication;
public event OnCheckContextEventHandler? OnCheckContext;
public event OnCheckContextEventHandler? OnCheckContextCompleted;
public event OnGetNewDataManagerEventHandler? OnGetNewDataManager;
public event DataManagerEventHandler? OnResetDataManager;
protected record PrivateParameterInfo(string Name, int Index);
@@ -51,6 +58,10 @@ public class ApiServer : IApiServer
public int MaxConcurentConnections { get; set; } = 5;
public IDataManager Manager => GetManager();
public bool ThreadedDataManager { get; set; }
public ApiServer(string apiUrl) : this(apiUrl, null)
{
}
@@ -61,16 +72,38 @@ public class ApiServer : IApiServer
this.httpListener = httpListener ?? CreateDefaultHttpListener();
}
private IDataManager GetManager()
{
var curThread = ThreadedDataManager ? Thread.CurrentThread : null;
var threadHolder = new ThreadHolder(curThread);
if (managers.TryGetValue(threadHolder, out var mgr))
return mgr;
if (OnGetNewDataManager?.Invoke(this, EventArgs.Empty) is not IDataManager manager)
throw new MissingDataManagerException();
managers.Add(threadHolder, manager);
return manager;
}
public virtual void ResetManager()
{
if (managers.Remove(new(ThreadedDataManager ? Thread.CurrentThread : null), out var manager))
OnResetDataManager?.Invoke(this, new(manager));
}
protected virtual HttpListener CreateDefaultHttpListener()
{
var httpListener = new HttpListener();
httpListener.TimeoutManager.IdleConnection = new TimeSpan(0, 10, 0);
httpListener.TimeoutManager.IdleConnection = new TimeSpan(0, 2, 0);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
httpListener.TimeoutManager.RequestQueue = new TimeSpan(0, 10, 0);
httpListener.TimeoutManager.HeaderWait = new TimeSpan(0, 10, 0);
httpListener.TimeoutManager.RequestQueue = new TimeSpan(0, 2, 0);
httpListener.TimeoutManager.HeaderWait = new TimeSpan(0, 2, 0);
}
return httpListener;
@@ -296,21 +329,27 @@ public class ApiServer : IApiServer
if (context is not null)
{
Log.Info("Request retrived for " + context.Request.RawUrl);
ResetManager();
OnCheckContext?.Invoke(this, new(context));
try
{
CheckContext(context);
success = true;
}
catch (MissingDataManagerException mdmex)
{
Log.Error("DataManager is not supported by this server instnace!", mdmex);
if (DebugMode) throw;
}
catch (Exception ex)
{
Log.Error("Error checking context", ex);
if (DebugMode)
throw;
if (DebugMode) throw;
}
finally
{
OnCheckContextCompleted?.Invoke(this, new(context));
ResetManager();
}
}