Skip to content

Commit

Permalink
issue #324: DescribeData API and implementation stub (#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
qkrorlqr committed Feb 9, 2024
1 parent 1ea41c4 commit feee281
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 11 deletions.
4 changes: 4 additions & 0 deletions cloud/filestore/libs/storage/api/tablet.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace NCloud::NFileStore::NStorage {
xxx(GetFileSystemConfig, __VA_ARGS__) \
xxx(GetStorageConfigFields, __VA_ARGS__) \
xxx(ChangeStorageConfig, __VA_ARGS__) \
xxx(DescribeData, __VA_ARGS__) \
// FILESTORE_TABLET_REQUESTS

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -57,6 +58,9 @@ struct TEvIndexTablet
EvChangeStorageConfigRequest = EvBegin + 13,
EvChangeStorageConfigResponse,

EvDescribeDataRequest = EvBegin + 15,
EvDescribeDataResponse,

EvEnd
};

Expand Down
88 changes: 82 additions & 6 deletions cloud/filestore/libs/storage/tablet/tablet_actor_readdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ STFUNC(TReadDataActor::StateWork)

////////////////////////////////////////////////////////////////////////////////

NProto::TError ValidateRequest(const NProto::TReadDataRequest& request, ui32 blockSize)
template <typename TReadRequest>
NProto::TError ValidateRequest(const TReadRequest& request, ui32 blockSize)
{
const TByteRange range(
request.GetOffset(),
Expand Down Expand Up @@ -447,7 +448,8 @@ void TIndexTabletActor::HandleReadData(
msg->Record,
byteRange,
alignedByteRange,
std::move(blockBuffer));
std::move(blockBuffer),
false /* describeOnly */);
}

void TIndexTabletActor::HandleReadDataCompleted(
Expand All @@ -463,6 +465,45 @@ void TIndexTabletActor::HandleReadDataCompleted(

////////////////////////////////////////////////////////////////////////////////

void TIndexTabletActor::HandleDescribeData(
const TEvIndexTablet::TEvDescribeDataRequest::TPtr& ev,
const TActorContext& ctx)
{
auto validator = [&] (const NProtoPrivate::TDescribeDataRequest& request) {
return ValidateRequest(request, GetBlockSize());
};

if (!AcceptRequest<TEvIndexTablet::TDescribeDataMethod>(ev, ctx, validator)) {
return;
}

auto* msg = ev->Get();
const TByteRange byteRange(
msg->Record.GetOffset(),
msg->Record.GetLength(),
GetBlockSize()
);

auto requestInfo = CreateRequestInfo(
ev->Sender,
ev->Cookie,
msg->CallContext);

TByteRange alignedByteRange = byteRange.AlignedSuperRange();
auto blockBuffer = CreateBlockBuffer(alignedByteRange);

ExecuteTx<TReadData>(
ctx,
std::move(requestInfo),
msg->Record,
byteRange,
alignedByteRange,
std::move(blockBuffer),
true /* describeOnly */);
}

////////////////////////////////////////////////////////////////////////////////

bool TIndexTabletActor::PrepareTx_ReadData(
const TActorContext& ctx,
TTransactionContext& tx,
Expand Down Expand Up @@ -584,19 +625,54 @@ void TIndexTabletActor::CompleteTx_ReadData(
const TActorContext& ctx,
TTxIndexTablet::TReadData& args)
{
if (FAILED(args.Error.GetCode())) {
auto response = std::make_unique<TEvService::TEvReadDataResponse>(args.Error);
CompleteResponse<TEvService::TReadDataMethod>(
if (args.DescribeOnly && !HasError(args.Error)) {
auto response =
std::make_unique<TEvIndexTablet::TEvDescribeDataResponse>();
auto& record = response->Record;

// TODO: fill record.{BlobPieces,FreshDataRanges}
Y_UNUSED(record);

CompleteResponse<TEvIndexTablet::TDescribeDataMethod>(
response->Record,
args.RequestInfo->CallContext,
ctx);

NCloud::Reply(ctx, *args.RequestInfo, std::move(response));

return;
}

if (HasError(args.Error)) {
if (args.DescribeOnly) {
auto response =
std::make_unique<TEvIndexTablet::TEvDescribeDataResponse>(args.Error);
CompleteResponse<TEvIndexTablet::TDescribeDataMethod>(
response->Record,
args.RequestInfo->CallContext,
ctx);

NCloud::Reply(ctx, *args.RequestInfo, std::move(response));
} else {
auto response =
std::make_unique<TEvService::TEvReadDataResponse>(args.Error);
CompleteResponse<TEvService::TReadDataMethod>(
response->Record,
args.RequestInfo->CallContext,
ctx);

NCloud::Reply(ctx, *args.RequestInfo, std::move(response));
}

return;
}

if (!ShouldReadBlobs(args.Blocks)) {
ApplyBytes(LogTag, args.AlignedByteRange, std::move(args.Bytes), *args.Buffer);
ApplyBytes(
LogTag,
args.AlignedByteRange,
std::move(args.Bytes),
*args.Buffer);

auto response = std::make_unique<TEvService::TEvReadDataResponse>();
CopyFileData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ template void TIndexTabletActor::CompleteResponse<ns::T##name##Method>(
// FILESTORE_IMPL_VALIDATE

FILESTORE_SERVICE(FILESTORE_GENERATE_IMPL, TEvService)
FILESTORE_GENERATE_IMPL(DescribeData, TEvIndexTablet)

#undef FILESTORE_GENERATE_IMPL

Expand Down
8 changes: 6 additions & 2 deletions cloud/filestore/libs/storage/tablet/tablet_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,7 @@ struct TTxIndexTablet
const TByteRange OriginByteRange;
const TByteRange AlignedByteRange;
/*const*/ IBlockBufferPtr Buffer;
const bool DescribeOnly;

ui64 CommitId = InvalidCommitId;
ui64 NodeId = InvalidNodeId;
Expand All @@ -1133,18 +1134,21 @@ struct TTxIndexTablet
// NOTE: should persist state across tx restarts
TSet<ui32> MixedBlocksRanges;

template <typename TReadRequest>
TReadData(
TRequestInfoPtr requestInfo,
const NProto::TReadDataRequest& request,
const TReadRequest& request,
TByteRange originByteRange,
TByteRange alignedByteRange,
IBlockBufferPtr buffer)
IBlockBufferPtr buffer,
bool describeOnly)
: TSessionAware(request)
, RequestInfo(std::move(requestInfo))
, Handle(request.GetHandle())
, OriginByteRange(originByteRange)
, AlignedByteRange(alignedByteRange)
, Buffer(std::move(buffer))
, DescribeOnly(describeOnly)
, Blocks(AlignedByteRange.BlockCount())
, Bytes(AlignedByteRange.BlockCount())
{
Expand Down
75 changes: 73 additions & 2 deletions cloud/filestore/private/api/protos/tablet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import "cloud/filestore/public/api/protos/fs.proto";
import "cloud/filestore/public/api/protos/headers.proto";
import "cloud/filestore/config/storage.proto";

import "contrib/ydb/core/protos/base.proto";

package NCloud.NFileStore.NProtoPrivate;

option go_package = "a.yandex-team.ru/cloud/filestore/private/api/protos";
Expand Down Expand Up @@ -209,7 +211,7 @@ message TGetFileSystemConfigResponse
}

////////////////////////////////////////////////////////////////////////////////
// GetStorageConfig fields request/response.
// GetStorageConfigFields request/response.

message TGetStorageConfigFieldsRequest
{
Expand All @@ -233,7 +235,7 @@ message TGetStorageConfigFieldsResponse
}

////////////////////////////////////////////////////////////////////////////////
// Change StorageConfig request/response
// ChangeStorageConfig request/response

message TChangeStorageConfigRequest
{
Expand All @@ -258,3 +260,72 @@ message TChangeStorageConfigResponse
// Result Storage config.
NProto.TStorageConfig StorageConfig = 2;
}

////////////////////////////////////////////////////////////////////////////////
// DescribeData request/response.

message TDescribeDataRequest
{
// Optional request headers.
NProto.THeaders Headers = 1;

// FileSystem identifier.
string FileSystemId = 2;

// Node.
uint64 NodeId = 3;

// IO handle.
uint64 Handle = 4;

// Starting offset for read.
uint64 Offset = 5;

// Number of bytes to read.
uint64 Length = 6;
}

// Represents actual data - for the data that is not stored in data channels as
// blobs yet.
message TFreshDataRange
{
// This offset is relative to the beginning of the inode.
uint64 Offset = 1;
// Data bytes.
bytes Content = 2;
}

// Represents a range of consecutive bytes inside some blob.
message TRangeInBlob
{
// This offset is relative to the beginning of the inode.
uint64 Offset = 1;
// This offset is relative to the beginning of the blob. Measured in bytes.
uint32 BlobOffset = 2;
uint32 Length = 3;
}

// Represents the ranges that need to be read from a single blob.
message TBlobPiece
{
// Blob id.
NKikimrProto.TLogoBlobID BlobId = 1;

// Group id.
uint32 BSGroupId = 2;

// Data ranges.
repeated TRangeInBlob Ranges = 3;
}

message TDescribeDataResponse
{
// Optional error, set only if error happened.
NCloud.NProto.TError Error = 1;

repeated TFreshDataRange FreshDataRanges = 2;
repeated TBlobPiece BlobPieces = 3;

// Optional response headers.
NProto.TResponseHeaders Headers = 1000;
}
4 changes: 3 additions & 1 deletion cloud/filestore/private/api/protos/ya.make
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
PROTO_LIBRARY(filestore-private-api-protos)

INCLUDE_TAGS(GO_PROTO)
EXCLUDE_TAGS(GO_PROTO)
EXCLUDE_TAGS(JAVA_PROTO)

PEERDIR(
cloud/filestore/config
cloud/filestore/public/api/protos
cloud/storage/core/protos

contrib/ydb/core/protos
)

SRCS(
Expand Down

0 comments on commit feee281

Please sign in to comment.