2023-06-21 06:28:40 +00:00
|
|
|
|
using Logging;
|
2023-04-13 07:33:10 +00:00
|
|
|
|
using Utils;
|
2023-04-12 11:53:55 +00:00
|
|
|
|
|
2023-09-12 11:32:06 +00:00
|
|
|
|
namespace Core
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2023-09-14 13:40:15 +00:00
|
|
|
|
public interface IHttp
|
|
|
|
|
{
|
2024-03-25 14:46:45 +00:00
|
|
|
|
T OnClient<T>(Func<HttpClient, T> action);
|
2024-03-26 08:10:06 +00:00
|
|
|
|
T OnClient<T>(Func<HttpClient, T> action, string description);
|
|
|
|
|
IEndpoint CreateEndpoint(Address address, string baseUrl, string? logAlias = null);
|
2023-09-14 13:40:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class Http : IHttp
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2023-10-24 07:41:37 +00:00
|
|
|
|
private static readonly object httpLock = new object();
|
2023-09-11 14:57:57 +00:00
|
|
|
|
private readonly ILog log;
|
2023-05-04 06:55:20 +00:00
|
|
|
|
private readonly ITimeSet timeSet;
|
2023-08-13 09:19:35 +00:00
|
|
|
|
private readonly Action<HttpClient> onClientCreated;
|
2023-04-12 11:53:55 +00:00
|
|
|
|
|
2024-03-26 08:10:06 +00:00
|
|
|
|
internal Http(ILog log, ITimeSet timeSet)
|
|
|
|
|
: this(log, timeSet, DoNothing)
|
2023-08-13 09:19:35 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 08:10:06 +00:00
|
|
|
|
internal Http(ILog log, ITimeSet timeSet, Action<HttpClient> onClientCreated)
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2023-04-30 08:08:32 +00:00
|
|
|
|
this.log = log;
|
2023-05-04 06:55:20 +00:00
|
|
|
|
this.timeSet = timeSet;
|
2023-08-13 09:19:35 +00:00
|
|
|
|
this.onClientCreated = onClientCreated;
|
2024-03-25 14:46:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public T OnClient<T>(Func<HttpClient, T> action)
|
|
|
|
|
{
|
2024-03-26 08:10:06 +00:00
|
|
|
|
return OnClient(action, GetDescription());
|
2023-04-12 11:53:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 08:10:06 +00:00
|
|
|
|
public T OnClient<T>(Func<HttpClient, T> action, string description)
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2024-03-26 08:10:06 +00:00
|
|
|
|
var client = GetClient();
|
2023-04-12 11:53:55 +00:00
|
|
|
|
|
2023-10-24 07:41:37 +00:00
|
|
|
|
return LockRetry(() =>
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2024-03-26 08:10:06 +00:00
|
|
|
|
return action(client);
|
|
|
|
|
}, description);
|
2023-08-31 09:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 08:10:06 +00:00
|
|
|
|
public IEndpoint CreateEndpoint(Address address, string baseUrl, string? logAlias = null)
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2024-03-26 08:10:06 +00:00
|
|
|
|
return new Endpoint(log, this, address, baseUrl, logAlias);
|
2023-04-12 11:53:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 08:10:06 +00:00
|
|
|
|
private string GetDescription()
|
2023-04-30 08:08:32 +00:00
|
|
|
|
{
|
2024-03-26 08:10:06 +00:00
|
|
|
|
// todo: check this:
|
|
|
|
|
return DebugStack.GetCallerName(skipFrames: 2);
|
2023-04-30 08:08:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-24 07:41:37 +00:00
|
|
|
|
private T LockRetry<T>(Func<T> operation, string description)
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
2023-10-24 07:41:37 +00:00
|
|
|
|
lock (httpLock)
|
|
|
|
|
{
|
|
|
|
|
return Time.Retry(operation, timeSet.HttpMaxNumberOfRetries(), timeSet.HttpCallRetryDelay(), description);
|
|
|
|
|
}
|
2023-04-19 08:42:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-04 06:55:20 +00:00
|
|
|
|
private HttpClient GetClient()
|
2023-04-12 11:53:55 +00:00
|
|
|
|
{
|
|
|
|
|
var client = new HttpClient();
|
2023-07-17 13:21:10 +00:00
|
|
|
|
client.Timeout = timeSet.HttpCallTimeout();
|
2023-08-13 09:19:35 +00:00
|
|
|
|
onClientCreated(client);
|
2023-04-12 11:53:55 +00:00
|
|
|
|
return client;
|
|
|
|
|
}
|
2023-08-13 09:19:35 +00:00
|
|
|
|
|
|
|
|
|
private static void DoNothing(HttpClient client)
|
|
|
|
|
{
|
|
|
|
|
}
|
2023-04-12 11:53:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|