33#include " datashard_impl.h"
44
55#include < ydb/core/protos/datashard_config.pb.h>
6+ #include < ydb/core/protos/tx_datashard.pb.h>
67
78#include < util/generic/maybe.h>
89#include < util/string/builder.h>
@@ -17,6 +18,11 @@ using namespace NActors;
1718using namespace NTable ;
1819using namespace NTabletFlatExecutor ;
1920
21+ void TCdcStreamScanManager::TStats::Serialize (NKikimrTxDataShard::TEvCdcStreamScanResponse_TStats& proto) const {
22+ proto.SetRowsProcessed (RowsProcessed);
23+ proto.SetBytesProcessed (BytesProcessed);
24+ }
25+
2026void TCdcStreamScanManager::Reset () {
2127 Scans.clear ();
2228 TxIdToPathId.clear ();
@@ -95,6 +101,7 @@ void TCdcStreamScanManager::Complete(const TPathId& streamPathId) {
95101 return ;
96102 }
97103
104+ CompletedScans[streamPathId] = it->second .Stats ;
98105 TxIdToPathId.erase (it->second .TxId );
99106 Scans.erase (it);
100107}
@@ -104,6 +111,15 @@ void TCdcStreamScanManager::Complete(ui64 txId) {
104111 Complete (TxIdToPathId.at (txId));
105112}
106113
114+ bool TCdcStreamScanManager::IsCompleted (const TPathId& streamPathId) const {
115+ return CompletedScans.contains (streamPathId);
116+ }
117+
118+ const TCdcStreamScanManager::TStats& TCdcStreamScanManager::GetCompletedStats (const TPathId& streamPathId) const {
119+ Y_ABORT_UNLESS (CompletedScans.contains (streamPathId));
120+ return CompletedScans.at (streamPathId);
121+ }
122+
107123TCdcStreamScanManager::TScanInfo* TCdcStreamScanManager::Get (const TPathId& streamPathId) {
108124 return Scans.FindPtr (streamPathId);
109125}
@@ -456,8 +472,7 @@ class TCdcStreamScan: public IActorCallback, public IScan {
456472 PathIdFromPathId (StreamPathId, response->Record .MutableStreamPathId ());
457473 response->Record .SetStatus (status);
458474 response->Record .SetErrorDescription (error);
459- response->Record .MutableStats ()->SetRowsProcessed (Stats.RowsProcessed );
460- response->Record .MutableStats ()->SetBytesProcessed (Stats.BytesProcessed );
475+ Stats.Serialize (*response->Record .MutableStats ());
461476
462477 Send (ReplyTo, std::move (response));
463478 }
@@ -572,11 +587,10 @@ class TDataShard::TTxCdcStreamScanRun: public TTransactionBase<TDataShard> {
572587 TEvDataShard::TEvCdcStreamScanRequest::TPtr Request;
573588 THolder<IEventHandle> Response; // response to sender or forward to scanner
574589
575- THolder<IEventHandle> MakeResponse (const TActorContext& ctx,
576- NKikimrTxDataShard::TEvCdcStreamScanResponse::EStatus status, const TString& error = {}) const
577- {
590+ template <typename ... Args>
591+ THolder<IEventHandle> MakeResponse (const TActorContext& ctx, Args&&... args) const {
578592 return MakeHolder<IEventHandle>(Request->Sender , ctx.SelfID , new TEvDataShard::TEvCdcStreamScanResponse (
579- Request->Get ()->Record , Self->TabletID (), status, error
593+ Request->Get ()->Record , Self->TabletID (), std::forward<Args>(args)...
580594 ));
581595 }
582596
@@ -643,6 +657,11 @@ class TDataShard::TTxCdcStreamScanRun: public TTransactionBase<TDataShard> {
643657 } else if (info->ScanId ) {
644658 return true ; // nop, scan actor will report state when it starts
645659 }
660+ } else if (Self->CdcStreamScanManager .IsCompleted (streamPathId)) {
661+ Response = MakeResponse (ctx, NKikimrTxDataShard::TEvCdcStreamScanResponse::DONE);
662+ Self->CdcStreamScanManager .GetCompletedStats (streamPathId).Serialize (
663+ *Response->Get <TEvDataShard::TEvCdcStreamScanResponse>()->Record .MutableStats ());
664+ return true ;
646665 } else if (Self->CdcStreamScanManager .Size ()) {
647666 Response = MakeResponse (ctx, NKikimrTxDataShard::TEvCdcStreamScanResponse::OVERLOADED);
648667 return true ;
0 commit comments