2
0
mirror of synced 2025-01-09 16:15:51 +00:00

98 lines
2.8 KiB
C#
Raw Normal View History

using Logging;
2023-04-13 09:33:10 +02:00
using Utils;
2023-04-12 13:53:55 +02:00
2023-09-12 13:32:06 +02:00
namespace Core
2023-04-12 13:53:55 +02:00
{
2023-09-14 15:40:15 +02:00
public interface IHttp
{
2024-03-25 15:46:45 +01:00
T OnClient<T>(Func<HttpClient, T> action);
T OnClient<T>(Func<HttpClient, T> action, string description);
T OnClient<T>(Func<HttpClient, T> action, Retry retry);
IEndpoint CreateEndpoint(Address address, string baseUrl, string? logAlias = null);
2023-09-14 15:40:15 +02:00
}
internal class Http : IHttp
2023-04-12 13:53:55 +02:00
{
private static object lockLock = new object();
2024-07-25 10:10:11 +02:00
private static readonly Dictionary<string, object> httpLocks = new Dictionary<string, object>();
2023-09-11 16:57:57 +02:00
private readonly ILog log;
private readonly ITimeSet timeSet;
2023-08-13 11:19:35 +02:00
private readonly Action<HttpClient> onClientCreated;
2024-07-25 10:10:11 +02:00
private readonly string id;
2023-04-12 13:53:55 +02:00
2024-07-25 10:10:11 +02:00
internal Http(string id, ILog log, ITimeSet timeSet)
: this(id, log, timeSet, DoNothing)
2023-08-13 11:19:35 +02:00
{
}
2024-07-25 10:10:11 +02:00
internal Http(string id, ILog log, ITimeSet timeSet, Action<HttpClient> onClientCreated)
2023-04-12 13:53:55 +02:00
{
2024-07-25 10:10:11 +02:00
this.id = id;
2023-04-30 10:08:32 +02:00
this.log = log;
this.timeSet = timeSet;
2023-08-13 11:19:35 +02:00
this.onClientCreated = onClientCreated;
2024-03-25 15:46:45 +01:00
}
public T OnClient<T>(Func<HttpClient, T> action)
{
return OnClient(action, GetDescription());
2023-04-12 13:53:55 +02:00
}
public T OnClient<T>(Func<HttpClient, T> action, string description)
{
var retry = new Retry(description, timeSet.HttpRetryTimeout(), timeSet.HttpCallRetryDelay(), f => { });
return OnClient(action, retry);
}
public T OnClient<T>(Func<HttpClient, T> action, Retry retry)
2023-04-12 13:53:55 +02:00
{
var client = GetClient();
2023-04-12 13:53:55 +02:00
return LockRetry(() =>
2023-04-12 13:53:55 +02:00
{
return action(client);
}, retry);
}
public IEndpoint CreateEndpoint(Address address, string baseUrl, string? logAlias = null)
2023-04-12 13:53:55 +02:00
{
return new Endpoint(log, this, address, baseUrl, logAlias);
2023-04-12 13:53:55 +02:00
}
private string GetDescription()
2023-04-30 10:08:32 +02:00
{
return DebugStack.GetCallerName(skipFrames: 2);
2023-04-30 10:08:32 +02:00
}
private T LockRetry<T>(Func<T> operation, Retry retry)
2023-04-12 13:53:55 +02:00
{
2024-07-25 10:10:11 +02:00
var httpLock = GetLock();
lock (httpLock)
{
return retry.Run(operation);
}
}
2024-07-25 10:10:11 +02:00
private object GetLock()
{
lock (lockLock) // I had to.
{
if (!httpLocks.ContainsKey(id)) httpLocks.Add(id, new object());
return httpLocks[id];
}
2024-07-25 10:10:11 +02:00
}
private HttpClient GetClient()
2023-04-12 13:53:55 +02:00
{
var client = new HttpClient();
client.Timeout = timeSet.HttpCallTimeout();
2023-08-13 11:19:35 +02:00
onClientCreated(client);
2023-04-12 13:53:55 +02:00
return client;
}
2023-08-13 11:19:35 +02:00
private static void DoNothing(HttpClient client)
{
}
2023-04-12 13:53:55 +02:00
}
}