[#20] Client: Optimize memory usage
All checks were successful
DCO / DCO (pull_request) Successful in 41s
All checks were successful
DCO / DCO (pull_request) Successful in 41s
Avoid memory allocation, use cache and static Signed-off-by: Pavel Gross <p.gross@yando.com>
This commit is contained in:
parent
35fe791406
commit
0ddde467cd
46 changed files with 596 additions and 372 deletions
|
@ -110,6 +110,6 @@ public class ContainerTest : ContainerTestsBase
|
|||
|
||||
var request = Mocker.Requests.First();
|
||||
|
||||
Assert.Equal(cid.ToGrpcMessage(), request.Request.Body.ContainerId);
|
||||
Assert.Equal(cid.ToMessage(), request.Request.Body.ContainerId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@ public class AsyncStreamReaderMock(string key, ObjectHeader objectHeader) : Serv
|
|||
{
|
||||
var header = new Header
|
||||
{
|
||||
ContainerId = objectHeader.ContainerId.ToGrpcMessage(),
|
||||
ContainerId = objectHeader.ContainerId.ToMessage(),
|
||||
PayloadLength = objectHeader.PayloadLength,
|
||||
Version = objectHeader.Version!.ToGrpcMessage(),
|
||||
OwnerId = objectHeader.OwnerId!.ToGrpcMessage()
|
||||
Version = objectHeader.Version!.ToMessage(),
|
||||
OwnerId = objectHeader.OwnerId!.ToMessage()
|
||||
};
|
||||
|
||||
foreach (var attr in objectHeader.Attributes)
|
||||
header.Attributes.Add(attr.ToGrpcMessage());
|
||||
header.Attributes.Add(attr.ToMessage());
|
||||
|
||||
var response = new GetResponse
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ public abstract class ServiceBase(string key)
|
|||
public static BasicAcl DefaultAcl { get; } = BasicAcl.PublicRW;
|
||||
public static PlacementPolicy DefaultPlacementPolicy { get; } = new PlacementPolicy(true, new Replica(1));
|
||||
|
||||
public Metadata ResponseMetaData => [];
|
||||
public static Metadata ResponseMetaData => [];
|
||||
|
||||
protected ResponseVerificationHeader GetResponseVerificationHeader(IResponse response)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ public abstract class ServiceBase(string key)
|
|||
|
||||
public ResponseMetaHeader ResponseMetaHeader => new()
|
||||
{
|
||||
Version = Version.ToGrpcMessage(),
|
||||
Version = Version.ToMessage(),
|
||||
Epoch = 100,
|
||||
Ttl = 1
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
|
|||
{
|
||||
var mock = new Mock<ContainerService.ContainerServiceClient>();
|
||||
|
||||
var grpcVersion = Version.ToGrpcMessage();
|
||||
var grpcVersion = Version.ToMessage();
|
||||
|
||||
PutResponse putResponse = new()
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
|
|||
},
|
||||
MetaHeader = new ResponseMetaHeader
|
||||
{
|
||||
Version = Version is null ? DefaultVersion.ToGrpcMessage() : Version.ToGrpcMessage(),
|
||||
Version = (Version is null ? DefaultVersion : Version).ToMessage(),
|
||||
Epoch = 100,
|
||||
Ttl = 1
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class ContainerMocker(string key) : ContainerServiceBase(key)
|
|||
Version = grpcVersion,
|
||||
Nonce = ByteString.CopyFrom(ContainerGuid.ToBytes()),
|
||||
BasicAcl = (uint)Acl,
|
||||
PlacementPolicy = PlacementPolicy.ToGrpcMessage()
|
||||
PlacementPolicy = PlacementPolicy.ToMessage()
|
||||
}
|
||||
},
|
||||
MetaHeader = ResponseMetaHeader
|
||||
|
|
|
@ -38,12 +38,12 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
|
|||
HeadResponse ??= new Header
|
||||
{
|
||||
CreationEpoch = 99,
|
||||
ContainerId = ObjectHeader.ContainerId.ToGrpcMessage(),
|
||||
ContainerId = ObjectHeader.ContainerId.ToMessage(),
|
||||
ObjectType = ObjectType.Regular,
|
||||
OwnerId = ObjectHeader.OwnerId!.ToGrpcMessage(),
|
||||
OwnerId = ObjectHeader.OwnerId!.ToMessage(),
|
||||
PayloadLength = 1,
|
||||
PayloadHash = new Refs.Checksum { Type = Refs.ChecksumType.Sha256, Sum = ByteString.CopyFrom(SHA256.HashData([0xff])) },
|
||||
Version = ObjectHeader.Version!.ToGrpcMessage()
|
||||
Version = ObjectHeader.Version!.ToMessage()
|
||||
};
|
||||
|
||||
HeadResponse headResponse = new()
|
||||
|
@ -89,7 +89,7 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
|
|||
|
||||
}
|
||||
|
||||
if (ResultObjectId != null)
|
||||
if (ResultObjectIds != null)
|
||||
{
|
||||
PutResponse putResponse = new()
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
|
|||
{
|
||||
ObjectId = new Refs.ObjectID
|
||||
{
|
||||
Value = ByteString.CopyFrom(ResultObjectId)
|
||||
Value = ByteString.CopyFrom(ResultObjectIds.ElementAt(0))
|
||||
}
|
||||
},
|
||||
MetaHeader = ResponseMetaHeader,
|
||||
|
@ -156,8 +156,8 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
|
|||
{
|
||||
Tombstone = new Refs.Address
|
||||
{
|
||||
ContainerId = ObjectHeader!.ContainerId.ToGrpcMessage(),
|
||||
ObjectId = ObjectId.ToGrpcMessage()
|
||||
ContainerId = ObjectHeader!.ContainerId.ToMessage(),
|
||||
ObjectId = ObjectId.ToMessage()
|
||||
}
|
||||
},
|
||||
MetaHeader = ResponseMetaHeader
|
||||
|
@ -195,7 +195,7 @@ public class ObjectMocker(string key) : ObjectServiceBase(key)
|
|||
|
||||
public Header? HeadResponse { get; set; }
|
||||
|
||||
public byte[]? ResultObjectId { get; set; }
|
||||
public List<byte[]>? ResultObjectIds { get; set; }
|
||||
|
||||
public ClientStreamWriter? ClientStreamWriter { get; private set; } = new ();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ using FrostFS.SDK.Cryptography;
|
|||
using FrostFS.SDK.ModelsV2;
|
||||
using FrostFS.SDK.ModelsV2.Enums;
|
||||
using FrostFS.SDK.ModelsV2.Netmap;
|
||||
using FrostFS.SDK.ProtosV2.Interfaces;
|
||||
using Google.Protobuf;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Security.Cryptography;
|
||||
|
@ -82,7 +83,7 @@ public class ObjectTest : ObjectTestsBase
|
|||
Assert.NotNull(result);
|
||||
|
||||
Assert.Equal(Mocker.ObjectHeader!.ContainerId.Value, result.Header.ContainerId.Value);
|
||||
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.ToGrpcMessage().ToString(), result.Header.OwnerId!.Value);
|
||||
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.Value, result.Header.OwnerId!.Value);
|
||||
Assert.Equal(Mocker.ObjectHeader.PayloadLength, result.Header.PayloadLength);
|
||||
Assert.Single(result.Header.Attributes);
|
||||
Assert.Equal(Mocker.ObjectHeader.Attributes[0].Key, result.Header.Attributes[0].Key);
|
||||
|
@ -92,7 +93,7 @@ public class ObjectTest : ObjectTestsBase
|
|||
[Fact]
|
||||
public async void PutObjectTest()
|
||||
{
|
||||
Mocker.ResultObjectId = SHA256.HashData([]);
|
||||
Mocker.ResultObjectIds = new([SHA256.HashData([])]);
|
||||
|
||||
Random rnd = new();
|
||||
var bytes = new byte[1024];
|
||||
|
@ -113,7 +114,7 @@ public class ObjectTest : ObjectTestsBase
|
|||
var body2 = sentMessages.ElementAt(1).GetBody() as Object.PutRequest.Types.Body;
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(Mocker.ResultObjectId, result.ToHash());
|
||||
Assert.Equal(Mocker.ResultObjectIds.First(), result.ToHash());
|
||||
|
||||
Assert.True(Mocker.ClientStreamWriter.CompletedTask);
|
||||
|
||||
|
@ -137,57 +138,85 @@ public class ObjectTest : ObjectTestsBase
|
|||
{
|
||||
Header = Mocker.ObjectHeader,
|
||||
Payload = new MemoryStream(bytes),
|
||||
BufferMaxSize = 1024,
|
||||
ClientCut = true
|
||||
};
|
||||
|
||||
Random rnd = new();
|
||||
|
||||
List<byte[]> objIds = new([new byte[32], new byte[32], new byte[32]]);
|
||||
rnd.NextBytes(objIds.ElementAt(0));
|
||||
rnd.NextBytes(objIds.ElementAt(1));
|
||||
rnd.NextBytes(objIds.ElementAt(2));
|
||||
|
||||
Mocker.ResultObjectIds = objIds;
|
||||
|
||||
var result = await GetClient().PutObjectAsync(param);
|
||||
|
||||
var sentMessages = Mocker.PutSingleRequests.ToArray();
|
||||
var singleObjects = Mocker.PutSingleRequests.ToArray();
|
||||
|
||||
Assert.Equal(4, sentMessages.Length);
|
||||
var streamObjects = Mocker.ClientStreamWriter.Messages.ToArray();
|
||||
|
||||
var object_0 = sentMessages[0].Body.Object;
|
||||
var object_1 = sentMessages[1].Body.Object;
|
||||
var object_2 = sentMessages[2].Body.Object;
|
||||
var object_3 = sentMessages[3].Body.Object;
|
||||
Assert.Single(singleObjects);
|
||||
|
||||
Assert.NotNull(object_0.Header.Split.SplitId);
|
||||
Assert.Null(object_0.Header.Split.Previous);
|
||||
Assert.Equal(blockSize, (int)object_0.Header.PayloadLength);
|
||||
Assert.Equal(bytes[..blockSize], object_0.Payload);
|
||||
Assert.True(object_0.Header.Attributes.Count == 0);
|
||||
Assert.Equal(11, streamObjects.Length);
|
||||
|
||||
Assert.Equal(object_0.Header.Split.SplitId, object_1.Header.Split.SplitId);
|
||||
Assert.Equal(object_0.ObjectId, object_1.Header.Split.Previous);
|
||||
Assert.Equal(blockSize, (int)object_1.Header.PayloadLength);
|
||||
Assert.Equal(bytes[blockSize..(blockSize * 2)], object_1.Payload);
|
||||
Assert.True(object_1.Header.Attributes.Count == 0);
|
||||
var bodies = streamObjects.Select(o => ((Object.PutRequest)o).Body).ToArray();
|
||||
|
||||
Assert.Equal(3, bodies.Count(b => b.Init != null));
|
||||
Assert.Equal(5, bodies.Count(b => b.Chunk.Length == 1024));
|
||||
|
||||
Assert.Equal(596, ((Object.PutRequest)streamObjects[10]).Body.Chunk.Length);
|
||||
|
||||
var linkObject = singleObjects[0].Body.Object;
|
||||
var header1 = bodies[0].Init.Header;
|
||||
var header2 = bodies[4].Init.Header;
|
||||
var header3 = bodies[8].Init.Header;
|
||||
|
||||
var payload1 = bodies[1].Chunk
|
||||
.Concat(bodies[2].Chunk)
|
||||
.Concat(bodies[3].Chunk)
|
||||
.ToArray();
|
||||
|
||||
var payload2 = bodies[5].Chunk
|
||||
.Concat(bodies[6].Chunk)
|
||||
.Concat(bodies[7].Chunk)
|
||||
.ToArray();
|
||||
|
||||
var payload3 = bodies[9].Chunk
|
||||
.Concat(bodies[10].Chunk)
|
||||
.ToArray();
|
||||
|
||||
Assert.NotNull(header1.Split.SplitId);
|
||||
Assert.Null(header1.Split.Previous);
|
||||
Assert.Equal(bytes[..blockSize], payload1);
|
||||
Assert.True(header1.Attributes.Count == 0);
|
||||
|
||||
Assert.Equal(header1.Split.SplitId, header2.Split.SplitId);
|
||||
Assert.Equal(objIds.ElementAt(0), header2.Split.Previous.Value);
|
||||
Assert.Equal(bytes[blockSize..(blockSize * 2)], payload2);
|
||||
Assert.True(header2.Attributes.Count == 0);
|
||||
|
||||
// last part
|
||||
Assert.NotNull(object_2.Header.Split.Parent);
|
||||
Assert.NotNull(object_2.Header.Split.ParentHeader);
|
||||
Assert.NotNull(object_2.Header.Split.ParentSignature);
|
||||
Assert.Equal(object_1.Header.Split.SplitId, object_2.Header.Split.SplitId);
|
||||
Assert.Equal(object_1.ObjectId, object_2.Header.Split.Previous);
|
||||
Assert.Equal(fileLength%blockSize, (int)object_2.Header.PayloadLength);
|
||||
Assert.Equal(bytes[((fileLength/blockSize) * blockSize)..fileLength], object_2.Payload);
|
||||
Assert.True(object_2.Header.Attributes.Count == 0);
|
||||
Assert.NotNull(header3.Split.Parent);
|
||||
Assert.NotNull(header3.Split.ParentHeader);
|
||||
Assert.NotNull(header3.Split.ParentSignature);
|
||||
Assert.Equal(header2.Split.SplitId, header3.Split.SplitId);
|
||||
Assert.Equal(bytes[((fileLength / blockSize) * blockSize)..fileLength], payload3);
|
||||
Assert.True(header3.Attributes.Count == 0);
|
||||
|
||||
// link object
|
||||
Assert.Equal(object_2.Header.Split.Parent, object_3.Header.Split.Parent);
|
||||
Assert.Equal(object_2.Header.Split.ParentHeader, object_3.Header.Split.ParentHeader);
|
||||
Assert.Equal(object_2.Header.Split.SplitId, object_3.Header.Split.SplitId);
|
||||
Assert.Equal(0, (int)object_3.Header.PayloadLength);
|
||||
Assert.Contains(object_0.ObjectId, object_3.Header.Split.Children);
|
||||
Assert.Contains(object_2.ObjectId, object_3.Header.Split.Children);
|
||||
Assert.Contains(object_2.ObjectId, object_3.Header.Split.Children);
|
||||
Assert.True(object_2.Header.Attributes.Count == 0);
|
||||
//link object
|
||||
Assert.Equal(header3.Split.Parent, linkObject.Header.Split.Parent);
|
||||
Assert.Equal(header3.Split.ParentHeader, linkObject.Header.Split.ParentHeader);
|
||||
Assert.Equal(header3.Split.SplitId, linkObject.Header.Split.SplitId);
|
||||
Assert.Equal(0, (int)linkObject.Header.PayloadLength);
|
||||
Assert.True(header3.Attributes.Count == 0);
|
||||
|
||||
Assert.Single(object_3.Header.Split.ParentHeader.Attributes);
|
||||
Assert.Equal("k", object_3.Header.Split.ParentHeader.Attributes[0].Key);
|
||||
Assert.Equal("v", object_3.Header.Split.ParentHeader.Attributes[0].Value);
|
||||
Assert.Single(linkObject.Header.Split.ParentHeader.Attributes);
|
||||
Assert.Equal("k", linkObject.Header.Split.ParentHeader.Attributes[0].Key);
|
||||
Assert.Equal("v", linkObject.Header.Split.ParentHeader.Attributes[0].Value);
|
||||
|
||||
var modelObjId = ObjectId.FromHash(object_3.Header.Split.Parent.Value.ToByteArray());
|
||||
var modelObjId = ObjectId.FromHash(linkObject.Header.Split.Parent.Value.ToByteArray());
|
||||
|
||||
Assert.Equal(result.Value, modelObjId.ToString());
|
||||
}
|
||||
|
@ -201,8 +230,8 @@ public class ObjectTest : ObjectTestsBase
|
|||
|
||||
var request = Mocker.DeleteRequests.FirstOrDefault();
|
||||
Assert.NotNull(request);
|
||||
Assert.Equal(ContainerId.ToGrpcMessage(), request.Body.Address.ContainerId);
|
||||
Assert.Equal(Mocker.ObjectId.ToGrpcMessage(), request.Body.Address.ObjectId);
|
||||
Assert.Equal(ContainerId.ToMessage().Value, request.Body.Address.ContainerId.Value);
|
||||
Assert.Equal(Mocker.ObjectId.ToMessage().Value, request.Body.Address.ObjectId.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -214,13 +243,13 @@ public class ObjectTest : ObjectTestsBase
|
|||
|
||||
var request = Mocker.HeadRequests.FirstOrDefault();
|
||||
Assert.NotNull(request);
|
||||
Assert.Equal(ContainerId.ToGrpcMessage(), request.Body.Address.ContainerId);
|
||||
Assert.Equal(Mocker.ObjectId.ToGrpcMessage(), request.Body.Address.ObjectId);
|
||||
Assert.Equal(ContainerId.ToMessage(), request.Body.Address.ContainerId);
|
||||
Assert.Equal(Mocker.ObjectId.ToMessage(), request.Body.Address.ObjectId);
|
||||
|
||||
Assert.NotNull(response);
|
||||
Assert.Equal(ContainerId.Value, response.ContainerId.Value);
|
||||
|
||||
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.ToGrpcMessage().ToString(), response.OwnerId!.Value);
|
||||
Assert.Equal(Mocker.ObjectHeader!.OwnerId!.Value, response.OwnerId!.Value);
|
||||
Assert.Equal(Mocker.ObjectHeader!.Version!.ToString(), response.Version!.ToString());
|
||||
|
||||
Assert.Equal(Mocker.HeadResponse!.PayloadLength, response.PayloadLength);
|
||||
|
|
|
@ -72,13 +72,14 @@ public class SmokeTests
|
|||
[Fact]
|
||||
public async void GetSessionTest()
|
||||
{
|
||||
var ecdsaKey = this.key.LoadWif();
|
||||
|
||||
using var client = Client.GetInstance(GetOptions(this.key, this.url));
|
||||
|
||||
var token = await client.CreateSessionAsync(new PrmSessionCreate(100));
|
||||
|
||||
var session = new Session.SessionToken().Deserialize(token.Token);
|
||||
|
||||
var ecdsaKey = this.key.LoadWif();
|
||||
|
||||
var owner = OwnerId.FromKey(ecdsaKey);
|
||||
|
||||
var ownerHash = Base58.Decode(owner.Value);
|
||||
|
@ -217,9 +218,10 @@ public class SmokeTests
|
|||
await foreach (var objId in client.SearchObjectsAsync(searchParam))
|
||||
{
|
||||
resultObjectsCount++;
|
||||
var objHeader = await client.GetObjectHeadAsync(new PrmObjectHeadGet(containerId, objId));
|
||||
}
|
||||
|
||||
Assert.True(1 == resultObjectsCount, $"Filter for {filter.Key} doesn't work");
|
||||
Assert.True(0 < resultObjectsCount, $"Filter for {filter.Key} doesn't work");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -403,14 +405,14 @@ public class SmokeTests
|
|||
[InlineData(2 * 64 * 1024 * 1024 + 256)]
|
||||
[InlineData(200)]
|
||||
public async void ClientCutScenarioTest(int objectSize)
|
||||
{
|
||||
{
|
||||
using var client = Client.GetInstance(GetOptions(this.key, this.url));
|
||||
|
||||
await Cleanup(client);
|
||||
|
||||
var createContainerParam = new PrmContainerCreate(new ModelsV2.Container(BasicAcl.PublicRW, new PlacementPolicy(true, new Replica(1))))
|
||||
{
|
||||
WaitParams = lightWait
|
||||
WaitParams = lightWait
|
||||
};
|
||||
|
||||
var containerId = await client.CreateContainerAsync(createContainerParam);
|
||||
|
@ -449,8 +451,8 @@ public class SmokeTests
|
|||
var objHeader = await client.GetObjectHeadAsync(new PrmObjectHeadGet(containerId, objectId));
|
||||
Assert.Equal((ulong)bytes.Length, objHeader.PayloadLength);
|
||||
Assert.Single(objHeader.Attributes);
|
||||
Assert.Equal("fileName", objHeader.Attributes.First().Key);
|
||||
Assert.Equal("test", objHeader.Attributes.First().Value);
|
||||
Assert.Equal("fileName", objHeader.Attributes[0].Key);
|
||||
Assert.Equal("test", objHeader.Attributes[0].Value);
|
||||
}
|
||||
|
||||
Assert.True(hasObject);
|
||||
|
@ -542,7 +544,7 @@ public class MetricsInterceptor() : Interceptor
|
|||
|
||||
watch.Stop();
|
||||
|
||||
// Do somethins with call info
|
||||
// Do something with call info
|
||||
// var elapsed = watch.ElapsedTicks * 1_000_000/Stopwatch.Frequency;
|
||||
|
||||
return response;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue