Skip to content

Commit a38873b

Browse files
authored
Merge c33c319 into fcc71af
2 parents fcc71af + c33c319 commit a38873b

File tree

2 files changed

+234
-209
lines changed

2 files changed

+234
-209
lines changed

ydb/library/yql/dq/actors/compute/dq_compute_actor_impl.h

Lines changed: 28 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -313,17 +313,7 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
313313
virtual void DoExecuteImpl() = 0;
314314
virtual void DoTerminateImpl() {}
315315

316-
virtual bool DoHandleChannelsAfterFinishImpl() {
317-
Y_ABORT_UNLESS(Checkpoints);
318-
319-
if (Checkpoints->HasPendingCheckpoint() && !Checkpoints->ComputeActorStateSaved() && ReadyToCheckpoint()) {
320-
Checkpoints->DoCheckpoint();
321-
}
322-
323-
// Send checkpoints to output channels.
324-
ProcessOutputsImpl(ERunStatus::Finished);
325-
return true; // returns true, when channels were handled synchronously
326-
}
316+
virtual bool DoHandleChannelsAfterFinishImpl() = 0;
327317

328318
void ProcessOutputsImpl(ERunStatus status) {
329319
ProcessOutputsState.LastRunStatus = status;
@@ -621,131 +611,50 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
621611
}
622612
}
623613

624-
public:
625-
i64 GetInputChannelFreeSpace(ui64 channelId) const override {
626-
const TInputChannelInfo* inputChannel = InputChannelsMap.FindPtr(channelId);
627-
YQL_ENSURE(inputChannel, "task: " << Task.GetId() << ", unknown input channelId: " << channelId);
628-
629-
return inputChannel->Channel->GetFreeSpace();
630-
}
631-
632-
void TakeInputChannelData(TChannelDataOOB&& channelData, bool ack) override {
633-
TInputChannelInfo* inputChannel = InputChannelsMap.FindPtr(channelData.Proto.GetChannelId());
634-
YQL_ENSURE(inputChannel, "task: " << Task.GetId() << ", unknown input channelId: " << channelData.Proto.GetChannelId());
635-
636-
auto channel = inputChannel->Channel;
637-
638-
if (channelData.RowCount()) {
639-
TDqSerializedBatch batch;
640-
batch.Proto = std::move(*channelData.Proto.MutableData());
641-
batch.Payload = std::move(channelData.Payload);
642-
auto guard = BindAllocator();
643-
channel->Push(std::move(batch));
644-
}
645-
646-
if (channelData.Proto.HasCheckpoint()) {
647-
Y_ABORT_UNLESS(inputChannel->CheckpointingMode != NDqProto::CHECKPOINTING_MODE_DISABLED);
648-
Y_ABORT_UNLESS(Checkpoints);
649-
const auto& checkpoint = channelData.Proto.GetCheckpoint();
650-
inputChannel->Pause(checkpoint);
651-
Checkpoints->RegisterCheckpoint(checkpoint, channelData.Proto.GetChannelId());
652-
}
653-
654-
if (channelData.Proto.GetFinished()) {
655-
channel->Finish();
656-
}
657-
658-
if (ack) {
659-
Channels->SendChannelDataAck(channel->GetChannelId(), channel->GetFreeSpace());
660-
}
661-
662-
ContinueExecute(EResumeSource::CATakeInput);
663-
}
664-
665-
void PeerFinished(ui64 channelId) override {
666-
TOutputChannelInfo* outputChannel = OutputChannelsMap.FindPtr(channelId);
667-
YQL_ENSURE(outputChannel, "task: " << Task.GetId() << ", output channelId: " << channelId);
668-
669-
outputChannel->Finished = true;
670-
outputChannel->Channel->Finish();
671-
672-
CA_LOG_D("task: " << Task.GetId() << ", output channelId: " << channelId << " finished prematurely, "
673-
<< " about to clear buffer");
674-
675-
{
676-
auto guard = BindAllocator();
677-
ui32 dropRows = outputChannel->Channel->Drop();
614+
protected: //TDqComputeActorChannels::ICallbacks
615+
//i64 GetInputChannelFreeSpace(ui64 channelId) is pure and must be overridded in derived class
678616

679-
CA_LOG_I("task: " << Task.GetId() << ", output channelId: " << channelId << " finished prematurely, "
680-
<< "drop " << dropRows << " rows");
681-
}
617+
//void TakeInputChannelData(TChannelDataOOB&& channelData, bool ack) is pure and must be overridded in derived class
682618

683-
DoExecute();
684-
}
619+
// void PeerFinished(ui64 channelId) is pure and must be overridded in derived class
685620

686-
void ResumeExecution(EResumeSource source) override {
621+
void ResumeExecution(EResumeSource source) override final{
687622
ContinueExecute(source);
688623
}
689624

690-
void OnSinkStateSaved(NDqProto::TSinkState&& state, ui64 outputIndex, const NDqProto::TCheckpoint& checkpoint) override {
625+
protected:
626+
void OnSinkStateSaved(NDqProto::TSinkState&& state, ui64 outputIndex, const NDqProto::TCheckpoint& checkpoint) override final {
691627
Y_ABORT_UNLESS(Checkpoints); // If we are checkpointing, we must have already constructed "checkpoints" object.
692628
Checkpoints->OnSinkStateSaved(std::move(state), outputIndex, checkpoint);
693629
}
694630

695-
void OnTransformStateSaved(NDqProto::TSinkState&& state, ui64 outputIndex, const NDqProto::TCheckpoint& checkpoint) override {
631+
void OnTransformStateSaved(NDqProto::TSinkState&& state, ui64 outputIndex, const NDqProto::TCheckpoint& checkpoint) override final {
696632
Y_ABORT_UNLESS(Checkpoints); // If we are checkpointing, we must have already constructed "checkpoints" object.
697633
Checkpoints->OnTransformStateSaved(std::move(state), outputIndex, checkpoint);
698634
}
699635

700-
void OnSinkFinished(ui64 outputIndex) override {
636+
void OnSinkFinished(ui64 outputIndex) override final {
701637
SinksMap.at(outputIndex).FinishIsAcknowledged = true;
702638
ContinueExecute(EResumeSource::CASinkFinished);
703639
}
704640

705-
void OnTransformFinished(ui64 outputIndex) override {
641+
void OnTransformFinished(ui64 outputIndex) override final {
706642
OutputTransformsMap.at(outputIndex).FinishIsAcknowledged = true;
707643
ContinueExecute(EResumeSource::CATransformFinished);
708644
}
645+
646+
protected: //TDqComputeActorCheckpoints::ICallbacks
647+
//bool ReadyToCheckpoint() is pure and must be overriden in a derived class
709648

710-
protected:
711-
bool ReadyToCheckpoint() const override {
712-
for (auto& [id, channelInfo] : InputChannelsMap) {
713-
if (channelInfo.CheckpointingMode == NDqProto::CHECKPOINTING_MODE_DISABLED) {
714-
continue;
715-
}
716-
717-
if (!channelInfo.IsPaused()) {
718-
return false;
719-
}
720-
if (!channelInfo.Channel->Empty()) {
721-
return false;
722-
}
723-
}
724-
return true;
725-
}
726-
727-
void CommitState(const NDqProto::TCheckpoint& checkpoint) override {
649+
void CommitState(const NDqProto::TCheckpoint& checkpoint) override final{
728650
CA_LOG_D("Commit state");
729651
for (auto& [inputIndex, source] : SourcesMap) {
730652
Y_ABORT_UNLESS(source.AsyncInput);
731653
source.AsyncInput->CommitState(checkpoint);
732654
}
733655
}
734656

735-
void InjectBarrierToOutputs(const NDqProto::TCheckpoint& checkpoint) override {
736-
Y_ABORT_UNLESS(CheckpointingMode != NDqProto::CHECKPOINTING_MODE_DISABLED);
737-
for (const auto& [id, channelInfo] : OutputChannelsMap) {
738-
if (!channelInfo.IsTransformOutput) {
739-
channelInfo.Channel->Push(NDqProto::TCheckpoint(checkpoint));
740-
}
741-
}
742-
for (const auto& [outputIndex, sink] : SinksMap) {
743-
sink.Buffer->Push(NDqProto::TCheckpoint(checkpoint));
744-
}
745-
for (const auto& [outputIndex, transform] : OutputTransformsMap) {
746-
transform.Buffer->Push(NDqProto::TCheckpoint(checkpoint));
747-
}
748-
}
657+
// void InjectBarrierToOutputs(const NDqProto::TCheckpoint& checkpoint) is pure and must be overriden in a derived class
749658

750659
void ResumeInputsByWatermark(TInstant watermark) {
751660
for (auto& [id, sourceInfo] : SourcesMap) {
@@ -771,15 +680,16 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
771680
}
772681
}
773682

774-
void ResumeInputsByCheckpoint() override {
683+
void ResumeInputsByCheckpoint() override final {
775684
for (auto& [id, channelInfo] : InputChannelsMap) {
776685
channelInfo.ResumeByCheckpoint();
777686
}
778687
}
779688

689+
protected:
780690
virtual void DoLoadRunnerState(TString&& blob) = 0;
781691

782-
void LoadState(NDqProto::TComputeActorState&& state) override {
692+
void LoadState(NDqProto::TComputeActorState&& state) override final {
783693
CA_LOG_D("Load state");
784694
TMaybe<TString> error = Nothing();
785695
const NDqProto::TMiniKqlProgramState& mkqlProgramState = state.GetMiniKqlProgram();
@@ -814,13 +724,13 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
814724
}
815725
}
816726

817-
void Start() override {
727+
void Start() override final {
818728
Running = true;
819729
State = NDqProto::COMPUTE_STATE_EXECUTING;
820730
ContinueExecute(EResumeSource::CAStart);
821731
}
822732

823-
void Stop() override {
733+
void Stop() override final {
824734
Running = false;
825735
State = NDqProto::COMPUTE_STATE_UNKNOWN;
826736
}
@@ -1255,99 +1165,12 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
12551165
NKikimr::NMiniKQL::TScopedAlloc& GetAllocator() {
12561166
return *Alloc.get();
12571167
}
1258-
private:
1259-
virtual const TDqMemoryQuota::TProfileStats* GetMemoryProfileStats() const {
1260-
Y_ABORT_UNLESS(MemoryQuota);
1261-
return MemoryQuota->GetProfileStats();
1262-
}
1263-
1264-
virtual void DrainOutputChannel(TOutputChannelInfo& outputChannel) {
1265-
YQL_ENSURE(!outputChannel.Finished || Checkpoints);
1266-
1267-
const bool wasFinished = outputChannel.Finished;
1268-
auto channelId = outputChannel.Channel->GetChannelId();
12691168

1270-
CA_LOG_T("About to drain channelId: " << channelId
1271-
<< ", hasPeer: " << outputChannel.HasPeer
1272-
<< ", finished: " << outputChannel.Channel->IsFinished());
1169+
virtual const TDqMemoryQuota::TProfileStats* GetMemoryProfileStats() const = 0;
12731170

1274-
ProcessOutputsState.HasDataToSend |= !outputChannel.Finished;
1275-
ProcessOutputsState.AllOutputsFinished &= outputChannel.Finished;
1171+
virtual void DrainOutputChannel(TOutputChannelInfo& outputChannel) = 0;
12761172

1277-
UpdateBlocked(outputChannel, !Channels->HasFreeMemoryInChannel(channelId));
1278-
1279-
ui32 sentChunks = 0;
1280-
while ((!outputChannel.Finished || Checkpoints) &&
1281-
Channels->HasFreeMemoryInChannel(outputChannel.ChannelId))
1282-
{
1283-
const static ui32 drainPackSize = 16;
1284-
std::vector<typename TOutputChannelInfo::TDrainedChannelMessage> channelData = outputChannel.DrainChannel(drainPackSize);
1285-
ui32 idx = 0;
1286-
for (auto&& i : channelData) {
1287-
if (auto* w = i.GetWatermarkOptional()) {
1288-
CA_LOG_I("Resume inputs by watermark");
1289-
// This is excessive, inputs should be resumed after async CA received response with watermark from task runner.
1290-
// But, let it be here, it's better to have the same code as in checkpoints
1291-
ResumeInputsByWatermark(TInstant::MicroSeconds(w->GetTimestampUs()));
1292-
}
1293-
if (i.GetCheckpointOptional()) {
1294-
CA_LOG_I("Resume inputs by checkpoint");
1295-
ResumeInputsByCheckpoint();
1296-
}
1297-
1298-
Channels->SendChannelData(i.BuildChannelData(outputChannel.ChannelId), ++idx == channelData.size());
1299-
++sentChunks;
1300-
}
1301-
if (drainPackSize != channelData.size()) {
1302-
if (!outputChannel.Finished) {
1303-
CA_LOG_T("output channelId: " << outputChannel.ChannelId << ", nothing to send and is not finished");
1304-
}
1305-
break;
1306-
}
1307-
}
1308-
1309-
ProcessOutputsState.HasDataToSend |= !outputChannel.Finished;
1310-
ProcessOutputsState.AllOutputsFinished &= outputChannel.Finished;
1311-
ProcessOutputsState.DataWasSent |= (!wasFinished && outputChannel.Finished) || sentChunks;
1312-
}
1313-
1314-
virtual void DrainAsyncOutput(ui64 outputIndex, TAsyncOutputInfoBase& outputInfo) {
1315-
ProcessOutputsState.AllOutputsFinished &= outputInfo.Finished;
1316-
if (outputInfo.Finished && !Checkpoints) {
1317-
return;
1318-
}
1319-
1320-
Y_ABORT_UNLESS(outputInfo.Buffer);
1321-
Y_ABORT_UNLESS(outputInfo.AsyncOutput);
1322-
Y_ABORT_UNLESS(outputInfo.Actor);
1323-
1324-
const ui32 allowedOvercommit = AllowedChannelsOvercommit();
1325-
const i64 sinkFreeSpaceBeforeSend = outputInfo.AsyncOutput->GetFreeSpace();
1326-
1327-
i64 toSend = sinkFreeSpaceBeforeSend + allowedOvercommit;
1328-
CA_LOG_D("About to drain async output " << outputIndex
1329-
<< ". FreeSpace: " << sinkFreeSpaceBeforeSend
1330-
<< ", allowedOvercommit: " << allowedOvercommit
1331-
<< ", toSend: " << toSend
1332-
<< ", finished: " << outputInfo.Buffer->IsFinished());
1333-
1334-
i64 sent = 0;
1335-
while (toSend > 0 && (!outputInfo.Finished || Checkpoints)) {
1336-
const ui32 sentChunk = SendDataChunkToAsyncOutput(outputIndex, outputInfo, toSend);
1337-
if (sentChunk == 0) {
1338-
break;
1339-
}
1340-
sent += sentChunk;
1341-
toSend = outputInfo.AsyncOutput->GetFreeSpace() + allowedOvercommit;
1342-
}
1343-
1344-
CA_LOG_D("Drain async output " << outputIndex
1345-
<< ". Free space decreased: " << (sinkFreeSpaceBeforeSend - outputInfo.AsyncOutput->GetFreeSpace())
1346-
<< ", sent data from buffer: " << sent);
1347-
1348-
ProcessOutputsState.HasDataToSend |= !outputInfo.Finished;
1349-
ProcessOutputsState.DataWasSent |= outputInfo.Finished || sent;
1350-
}
1173+
virtual void DrainAsyncOutput(ui64 outputIndex, TAsyncOutputInfoBase& outputInfo) = 0;
13511174

13521175
ui32 SendDataChunkToAsyncOutput(ui64 outputIndex, TAsyncOutputInfoBase& outputInfo, ui64 bytes) {
13531176
auto sink = outputInfo.Buffer;
@@ -1599,7 +1422,7 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
15991422
InternalError(fatalCode, issues);
16001423
}
16011424

1602-
void OnSinkError(ui64 outputIndex, const TIssues& issues, NYql::NDqProto::StatusIds::StatusCode fatalCode) override {
1425+
void OnSinkError(ui64 outputIndex, const TIssues& issues, NYql::NDqProto::StatusIds::StatusCode fatalCode) override final {
16031426
if (fatalCode == NYql::NDqProto::StatusIds::UNSPECIFIED) {
16041427
SinksMap.at(outputIndex).IssuesBuffer.Push(issues);
16051428
return;
@@ -1609,7 +1432,7 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
16091432
InternalError(fatalCode, issues);
16101433
}
16111434

1612-
void OnOutputTransformError(ui64 outputIndex, const TIssues& issues, NYql::NDqProto::StatusIds::StatusCode fatalCode) override {
1435+
void OnOutputTransformError(ui64 outputIndex, const TIssues& issues, NYql::NDqProto::StatusIds::StatusCode fatalCode) override final {
16131436
if (fatalCode == NYql::NDqProto::StatusIds::UNSPECIFIED) {
16141437
OutputTransformsMap.at(outputIndex).IssuesBuffer.Push(issues);
16151438
return;
@@ -1635,7 +1458,7 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
16351458
return true;
16361459
}
16371460

1638-
virtual ui64 CalcMkqlMemoryLimit() {
1461+
ui64 CalcMkqlMemoryLimit() {
16391462
auto& opts = Task.GetProgram().GetSettings();
16401463
return opts.GetHasMapJoin()/* || opts.GetHasSort()*/
16411464
? MemoryLimits.MkqlHeavyProgramMemoryLimit
@@ -1738,9 +1561,7 @@ class TDqComputeActorBase : public NActors::TActorBootstrapped<TDerived>
17381561
virtual const NYql::NDq::TTaskRunnerStatsBase* GetTaskRunnerStats() = 0;
17391562
virtual const NYql::NDq::TDqMeteringStats* GetMeteringStats() = 0;
17401563

1741-
virtual const IDqAsyncOutputBuffer* GetSink(ui64, const TAsyncOutputInfoBase& sinkInfo) const {
1742-
return sinkInfo.Buffer.Get();
1743-
}
1564+
virtual const IDqAsyncOutputBuffer* GetSink(ui64 outputIdx, const TAsyncOutputInfoBase& sinkInfo) const = 0;
17441565

17451566
public:
17461567

0 commit comments

Comments
 (0)