[#24] Client: Implement pool part1

first iteration - base classes and methods

Signed-off-by: Pavel Gross <p.gross@yadro.com>
This commit is contained in:
Pavel Gross 2024-10-21 10:48:00 +03:00
parent d1271df207
commit c9a75ea025
72 changed files with 2786 additions and 468 deletions

View file

@ -6,10 +6,12 @@ using System.Threading.Tasks;
using Frostfs.V2.Ape;
using Frostfs.V2.Apemanager;
using FrostFS.Accounting;
using FrostFS.Container;
using FrostFS.Netmap;
using FrostFS.Object;
using FrostFS.SDK.ClientV2.Interfaces;
using FrostFS.SDK.ClientV2.Services;
using FrostFS.SDK.Cryptography;
using FrostFS.Session;
@ -35,7 +37,9 @@ public class FrostFSClient : IFrostFSClient
internal ObjectService.ObjectServiceClient? ObjectServiceClient { get; set; }
internal ClientEnvironment ClientCtx { get; set; }
internal AccountingService.AccountingServiceClient? AccountingServiceClient { get; set; }
internal EnvironmentContext ClientCtx { get; set; }
public static IFrostFSClient GetInstance(IOptions<ClientSettings> clientOptions, GrpcChannelOptions? channelOptions = null)
{
@ -89,7 +93,7 @@ public class FrostFSClient : IFrostFSClient
var ecdsaKey = settings.Value.Key.LoadWif();
FrostFsOwner.FromKey(ecdsaKey);
ClientCtx = new ClientEnvironment(
ClientCtx = new EnvironmentContext(
client: this,
key: ecdsaKey,
owner: FrostFsOwner.FromKey(ecdsaKey),
@ -110,7 +114,7 @@ public class FrostFSClient : IFrostFSClient
var channel = InitGrpcChannel(clientSettings.Host, channelOptions);
ClientCtx = new ClientEnvironment(
ClientCtx = new EnvironmentContext(
this,
key: null,
owner: null,
@ -131,7 +135,7 @@ public class FrostFSClient : IFrostFSClient
var channel = InitGrpcChannel(clientSettings.Host, channelOptions);
ClientCtx = new ClientEnvironment(
ClientCtx = new EnvironmentContext(
this,
key: ecdsaKey,
owner: FrostFsOwner.FromKey(ecdsaKey),
@ -142,6 +146,16 @@ public class FrostFSClient : IFrostFSClient
// CheckFrostFsVersionSupport(new Context { Timeout = TimeSpan.FromSeconds(20) });
}
internal FrostFSClient(WrapperPrm prm)
{
ClientCtx = new EnvironmentContext(
client: this,
key: prm.Key,
owner: FrostFsOwner.FromKey(prm.Key!),
channel: InitGrpcChannel(prm.Address, null), //prm.GrpcChannelOptions),
version: new FrostFsVersion(2, 13));
}
public void Dispose()
{
Dispose(true);
@ -305,16 +319,16 @@ public class FrostFSClient : IFrostFSClient
}
#endregion
#region SessionImplementation
#region Session Implementation
public async Task<FrostFsSessionToken> CreateSessionAsync(PrmSessionCreate args)
{
if (args is null)
throw new ArgumentNullException(nameof(args));
var session = await CreateSessionInternalAsync(args).ConfigureAwait(false);
var token = session.Serialize();
return new FrostFsSessionToken(token);
var token = session.Serialize();
return new FrostFsSessionToken(token, session.Body.Id.ToUuid());
}
internal Task<SessionToken> CreateSessionInternalAsync(PrmSessionCreate args)
@ -327,8 +341,18 @@ public class FrostFSClient : IFrostFSClient
}
#endregion
#region Accounting Implementation
public async Task<Accounting.Decimal> GetBalanceAsync(PrmBalance? args)
{
args ??= new PrmBalance();
var service = GetAccouningService(args);
return await service.GetBallance(args).ConfigureAwait(false);
}
#endregion
#region ToolsImplementation
public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, Context ctx)
public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, CallContext ctx)
{
if (header == null)
throw new ArgumentNullException(nameof(header));
@ -337,7 +361,7 @@ public class FrostFSClient : IFrostFSClient
}
#endregion
private async void CheckFrostFsVersionSupport(Context? ctx = default)
private async void CheckFrostFsVersionSupport(CallContext? ctx = default)
{
var args = new PrmNodeInfo { Context = ctx };
@ -359,7 +383,7 @@ public class FrostFSClient : IFrostFSClient
if (isDisposed)
throw new InvalidObjectException("Client is disposed.");
ctx.Context ??= new Context();
ctx.Context ??= new CallContext();
if (ctx.Context.Key == null)
{
@ -441,6 +465,16 @@ public class FrostFSClient : IFrostFSClient
return new ApeManagerServiceProvider(client, ClientCtx);
}
private AccountingServiceProvider GetAccouningService(IContext ctx)
{
var callInvoker = SetupEnvironment(ctx);
var client = AccountingServiceClient ?? (callInvoker != null
? new AccountingService.AccountingServiceClient(callInvoker)
: new AccountingService.AccountingServiceClient(ClientCtx.Channel));
return new AccountingServiceProvider(client, ClientCtx);
}
private ContainerServiceProvider GetContainerService(IContext ctx)
{
var callInvoker = SetupEnvironment(ctx);
@ -461,6 +495,16 @@ public class FrostFSClient : IFrostFSClient
return new ObjectServiceProvider(client, ClientCtx);
}
private AccountingServiceProvider GetAccountService(IContext ctx)
{
var callInvoker = SetupEnvironment(ctx);
var client = AccountingServiceClient ?? (callInvoker != null
? new AccountingService.AccountingServiceClient(callInvoker)
: new AccountingService.AccountingServiceClient(ClientCtx.Channel));
return new AccountingServiceProvider(client, ClientCtx);
}
private static GrpcChannel InitGrpcChannel(string host, GrpcChannelOptions? channelOptions)
{
try
@ -480,4 +524,31 @@ public class FrostFSClient : IFrostFSClient
throw new ArgumentException($"Host '{host}' has invalid format. Error: {e.Message}");
}
}
public async Task<string?> Dial(CallContext ctx)
{
try
{
var prm = new PrmBalance { Context = ctx };
var service = GetAccouningService(prm);
var balance = await service.GetBallance(prm).ConfigureAwait(false);
return null;
}
catch (FrostFsException ex)
{
return ex.Message;
}
}
public bool RestartIfUnhealthy(CallContext ctx)
{
throw new NotImplementedException();
}
public void Close()
{
Dispose();
}
}