11#include " actors.h"
22
3+ #include < library/cpp/colorizer/colors.h>
4+
35#include < ydb/core/kqp/common/simple/services.h>
46#include < ydb/core/kqp/rm_service/kqp_rm_service.h>
57
@@ -10,26 +12,25 @@ namespace {
1012
1113class TRunScriptActorMock : public NActors ::TActorBootstrapped<TRunScriptActorMock> {
1214public:
13- TRunScriptActorMock (THolder<NKikimr::NKqp::TEvKqp::TEvQueryRequest> request,
14- NThreading::TPromise<TQueryResponse> promise, ui64 resultRowsLimit, ui64 resultSizeLimit,
15- TProgressCallback progressCallback)
16- : Request_(std::move(request))
15+ TRunScriptActorMock (TQueryRequest request, NThreading::TPromise<TQueryResponse> promise, TProgressCallback progressCallback)
16+ : TargetNode(request.TargetNode)
17+ , Request_(std::move(request.Event))
1718 , Promise_(promise)
1819 , ResultRowsLimit_(std::numeric_limits<ui64>::max())
1920 , ResultSizeLimit_(std::numeric_limits<i64 >::max())
2021 , ProgressCallback_(progressCallback)
2122 {
22- if (resultRowsLimit ) {
23- ResultRowsLimit_ = resultRowsLimit ;
23+ if (request. ResultRowsLimit ) {
24+ ResultRowsLimit_ = request. ResultRowsLimit ;
2425 }
25- if (resultSizeLimit ) {
26- ResultSizeLimit_ = resultSizeLimit ;
26+ if (request. ResultSizeLimit ) {
27+ ResultSizeLimit_ = request. ResultSizeLimit ;
2728 }
2829 }
2930
3031 void Bootstrap () {
3132 NActors::ActorIdToProto (SelfId (), Request_->Record .MutableRequestActorId ());
32- Send (NKikimr::NKqp::MakeKqpProxyID (SelfId (). NodeId () ), std::move (Request_));
33+ Send (NKikimr::NKqp::MakeKqpProxyID (TargetNode ), std::move (Request_));
3334
3435 Become (&TRunScriptActorMock::StateFunc);
3536 }
@@ -88,7 +89,8 @@ class TRunScriptActorMock : public NActors::TActorBootstrapped<TRunScriptActorMo
8889 }
8990
9091private:
91- THolder<NKikimr::NKqp::TEvKqp::TEvQueryRequest> Request_;
92+ ui32 TargetNode = 0 ;
93+ std::unique_ptr<NKikimr::NKqp::TEvKqp::TEvQueryRequest> Request_;
9294 NThreading::TPromise<TQueryResponse> Promise_;
9395 ui64 ResultRowsLimit_;
9496 ui64 ResultSizeLimit_;
@@ -97,25 +99,104 @@ class TRunScriptActorMock : public NActors::TActorBootstrapped<TRunScriptActorMo
9799 std::vector<ui64> ResultSetSizes_;
98100};
99101
100- class TResourcesWaiterActor : public NActors ::TActorBootstrapped<TResourcesWaiterActor> {
101- struct TEvPrivate {
102- enum EEv : ui32 {
103- EvResourcesInfo = EventSpaceBegin (NActors::TEvents::ES_PRIVATE),
102+ class TAsyncQueryRunnerActor : public NActors ::TActor<TAsyncQueryRunnerActor> {
103+ using TBase = NActors::TActor<TAsyncQueryRunnerActor>;
104+
105+ public:
106+ TAsyncQueryRunnerActor (ui64 inFlightLimit)
107+ : TBase(&TAsyncQueryRunnerActor::StateFunc)
108+ , InFlightLimit_(inFlightLimit)
109+ {}
110+
111+ STRICT_STFUNC (StateFunc,
112+ hFunc (TEvPrivate::TEvStartAsyncQuery, Handle);
113+ hFunc (TEvPrivate::TEvAsyncQueryFinished, Handle);
114+ hFunc (TEvPrivate::TEvFinalizeAsyncQueryRunner, Handle);
115+ )
116+
117+ void Handle (TEvPrivate::TEvStartAsyncQuery::TPtr& ev) {
118+ DelayedRequests_.emplace (std::move (ev));
119+ StartDelayedRequests ();
120+ }
121+
122+ void Handle (TEvPrivate::TEvAsyncQueryFinished::TPtr& ev) {
123+ const ui64 requestId = ev->Get ()->RequestId ;
124+ RunningRequests_.erase (requestId);
125+
126+ const auto & response = ev->Get ()->Result .Response ->Get ()->Record .GetRef ();
127+ const auto status = response.GetYdbStatus ();
128+
129+ if (status == Ydb::StatusIds::SUCCESS) {
130+ Completed_++;
131+ Cout << CoutColors_.Green () << TInstant::Now ().ToIsoStringLocal () << " Request #" << requestId << " completed. " << CoutColors_.Yellow () << GetInfoString () << CoutColors_.Default () << Endl;
132+ } else {
133+ Failed_++;
134+ NYql::TIssues issues;
135+ NYql::IssuesFromMessage (response.GetResponse ().GetQueryIssues (), issues);
136+ Cout << CoutColors_.Red () << TInstant::Now ().ToIsoStringLocal () << " Request #" << requestId << " failed " << status << " . " << CoutColors_.Yellow () << GetInfoString () << " \n " << CoutColors_.Red () << " Issues:\n " << issues.ToString () << CoutColors_.Default ();
137+ }
138+
139+ StartDelayedRequests ();
140+ TryFinalize ();
141+ }
142+
143+ void Handle (TEvPrivate::TEvFinalizeAsyncQueryRunner::TPtr& ev) {
144+ FinalizePromise_ = ev->Get ()->FinalizePromise ;
145+ if (!TryFinalize ()) {
146+ Cout << CoutColors_.Yellow () << TInstant::Now ().ToIsoStringLocal () << " Waiting for " << DelayedRequests_.size () + RunningRequests_.size () << " async queries..." << CoutColors_.Default () << Endl;
147+ }
148+ }
104149
105- EvEnd
106- };
150+ private:
151+ void StartDelayedRequests () {
152+ while (!DelayedRequests_.empty () && (!InFlightLimit_ || RunningRequests_.size () < InFlightLimit_)) {
153+ auto request = std::move (DelayedRequests_.front ());
154+ DelayedRequests_.pop ();
155+
156+ auto promise = NThreading::NewPromise<TQueryResponse>();
157+ Register (CreateRunScriptActorMock (std::move (request->Get ()->Request ), promise, nullptr ));
158+ RunningRequests_[RequestId_] = promise.GetFuture ().Subscribe ([id = RequestId_, this ](const NThreading::TFuture<TQueryResponse>& f) {
159+ Send (SelfId (), new TEvPrivate::TEvAsyncQueryFinished (id, std::move (f.GetValue ())));
160+ });
161+
162+ MaxInFlight_ = std::max (MaxInFlight_, RunningRequests_.size ());
163+ Cout << TStringBuilder () << CoutColors_.Cyan () << TInstant::Now ().ToIsoStringLocal () << " Request #" << RequestId_ << " started. " << CoutColors_.Yellow () << GetInfoString () << CoutColors_.Default () << " \n " ;
164+
165+ RequestId_++;
166+ request->Get ()->StartPromise .SetValue ();
167+ }
168+ }
107169
108- static_assert (EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), " expect EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE)" );
170+ bool TryFinalize () {
171+ if (!FinalizePromise_ || !RunningRequests_.empty ()) {
172+ return false ;
173+ }
109174
110- struct TEvResourcesInfo : public NActors ::TEventLocal<TEvResourcesInfo, EvResourcesInfo> {
111- explicit TEvResourcesInfo ( i32 nodeCount)
112- : NodeCount(nodeCount)
113- { }
175+ FinalizePromise_-> SetValue ();
176+ PassAway ();
177+ return true ;
178+ }
114179
115- const i32 NodeCount;
116- };
117- };
180+ TString GetInfoString () const {
181+ return TStringBuilder () << " completed: " << Completed_ << " , failed: " << Failed_ << " , in flight: " << RunningRequests_.size () << " , max in flight: " << MaxInFlight_ << " , spend time: " << TInstant::Now () - StartTime_;
182+ }
183+
184+ private:
185+ const ui64 InFlightLimit_;
186+ const TInstant StartTime_ = TInstant::Now();
187+ const NColorizer::TColors CoutColors_ = NColorizer::AutoColors(Cout);
188+
189+ std::optional<NThreading::TPromise<void >> FinalizePromise_;
190+ std::queue<TEvPrivate::TEvStartAsyncQuery::TPtr> DelayedRequests_;
191+ std::unordered_map<ui64, NThreading::TFuture<TQueryResponse>> RunningRequests_;
192+
193+ ui64 RequestId_ = 1 ;
194+ ui64 MaxInFlight_ = 0 ;
195+ ui64 Completed_ = 0 ;
196+ ui64 Failed_ = 0 ;
197+ };
118198
199+ class TResourcesWaiterActor : public NActors ::TActorBootstrapped<TResourcesWaiterActor> {
119200 static constexpr TDuration REFRESH_PERIOD = TDuration::MilliSeconds(10 );
120201
121202public:
@@ -183,10 +264,12 @@ class TResourcesWaiterActor : public NActors::TActorBootstrapped<TResourcesWaite
183264
184265} // anonymous namespace
185266
186- NActors::IActor* CreateRunScriptActorMock (THolder<NKikimr::NKqp::TEvKqp::TEvQueryRequest> request,
187- NThreading::TPromise<TQueryResponse> promise, ui64 resultRowsLimit, ui64 resultSizeLimit,
188- TProgressCallback progressCallback) {
189- return new TRunScriptActorMock (std::move (request), promise, resultRowsLimit, resultSizeLimit, progressCallback);
267+ NActors::IActor* CreateRunScriptActorMock (TQueryRequest request, NThreading::TPromise<TQueryResponse> promise, TProgressCallback progressCallback) {
268+ return new TRunScriptActorMock (std::move (request), promise, progressCallback);
269+ }
270+
271+ NActors::IActor* CreateAsyncQueryRunnerActor (ui64 inFlightLimit) {
272+ return new TAsyncQueryRunnerActor (inFlightLimit);
190273}
191274
192275NActors::IActor* CreateResourcesWaiterActor (NThreading::TPromise<void > promise, i32 expectedNodeCount) {
0 commit comments