4
4
#include < ydb/core/fq/libs/row_dispatcher/events/data_plane.h>
5
5
#include < ydb/core/fq/libs/row_dispatcher/format_handler/common/common.h>
6
6
7
+ #include < ydb/library/actors/core/actor_bootstrapped.h>
7
8
#include < ydb/library/actors/core/hfunc.h>
8
9
9
10
#include < yql/essentials/public/purecalc/common/interface.h>
@@ -12,26 +13,47 @@ namespace NFq::NRowDispatcher {
12
13
13
14
namespace {
14
15
15
- class TPurecalcCompileService : public NActors ::TActor<TPurecalcCompileService> {
16
- using TBase = NActors::TActor<TPurecalcCompileService>;
16
+ struct TEvPrivate {
17
+ // Event ids
18
+ enum EEv : ui32 {
19
+ EvCompileFinished = EventSpaceBegin (NActors::TEvents::ES_PRIVATE),
20
+ EvEnd
21
+ };
22
+
23
+ static_assert (EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), " expect EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE)" );
24
+
25
+ // Events
26
+ struct TEvCompileFinished : public NActors ::TEventLocal<TEvCompileFinished, EvCompileFinished> {
27
+ TEvCompileFinished (NActors::TActorId requestActor, ui64 requestId)
28
+ : RequestActor(requestActor)
29
+ , RequestId(requestId)
30
+ {}
31
+
32
+ const NActors::TActorId RequestActor;
33
+ const ui64 RequestId;
34
+ };
35
+ };
17
36
37
+ class TPurecalcCompileActor : public NActors ::TActorBootstrapped<TPurecalcCompileActor> {
18
38
public:
19
- TPurecalcCompileService ()
20
- : TBase(&TPurecalcCompileService::StateFunc)
21
- , LogPrefix(" TPurecalcCompileService: " )
39
+ TPurecalcCompileActor (NActors::TActorId owner, NYql::NPureCalc::IProgramFactoryPtr factory, TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr request)
40
+ : Owner(owner)
41
+ , Factory(factory)
42
+ , LogPrefix(TStringBuilder() << " TPurecalcCompileActor " << request->Sender << " [id " << request->Cookie << " ]: " )
43
+ , Request(std::move(request))
22
44
{}
23
45
24
- STRICT_STFUNC (StateFunc,
25
- hFunc (TEvRowDispatcher::TEvPurecalcCompileRequest, Handle );
26
- )
46
+ void Bootstrap () {
47
+ Y_DEFER {
48
+ Finish ();
49
+ };
27
50
28
- void Handle (TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr& ev) {
29
- LOG_ROW_DISPATCHER_TRACE (" Got compile request with id: " << ev->Cookie );
30
- IProgramHolder::TPtr programHolder = std::move (ev->Get ()->ProgramHolder );
51
+ LOG_ROW_DISPATCHER_TRACE (" Started compile request" );
52
+ IProgramHolder::TPtr programHolder = std::move (Request->Get ()->ProgramHolder );
31
53
32
54
TStatus status = TStatus::Success ();
33
55
try {
34
- programHolder->CreateProgram (GetOrCreateFactory (ev-> Get ()-> Settings ) );
56
+ programHolder->CreateProgram (Factory );
35
57
} catch (const NYql::NPureCalc::TCompileError& error) {
36
58
status = TStatus::Fail (EStatusId::INTERNAL_ERROR, TStringBuilder () << " Compile issues: " << error.GetIssues ())
37
59
.AddIssue (TStringBuilder () << " Final yql: " << error.GetYql ())
@@ -41,15 +63,120 @@ class TPurecalcCompileService : public NActors::TActor<TPurecalcCompileService>
41
63
}
42
64
43
65
if (status.IsFail ()) {
44
- LOG_ROW_DISPATCHER_ERROR (" Compilation failed for request with id: " << ev-> Cookie );
45
- Send (ev ->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (status.GetStatus (), status.GetErrorDescription ()), 0 , ev ->Cookie );
66
+ LOG_ROW_DISPATCHER_ERROR (" Compilation failed for request" );
67
+ Send (Request ->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (status.GetStatus (), status.GetErrorDescription ()), 0 , Request ->Cookie );
46
68
} else {
47
- LOG_ROW_DISPATCHER_TRACE (" Compilation completed for request with id: " << ev-> Cookie );
48
- Send (ev ->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (std::move (programHolder)), 0 , ev ->Cookie );
69
+ LOG_ROW_DISPATCHER_TRACE (" Compilation completed for request" );
70
+ Send (Request ->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (std::move (programHolder)), 0 , Request ->Cookie );
49
71
}
50
72
}
51
73
52
74
private:
75
+ void Finish () {
76
+ Send (Owner, new TEvPrivate::TEvCompileFinished (Request->Sender , Request->Cookie ));
77
+ PassAway ();
78
+ }
79
+
80
+ private:
81
+ const NActors::TActorId Owner;
82
+ const NYql::NPureCalc::IProgramFactoryPtr Factory;
83
+ const TString LogPrefix;
84
+
85
+ TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr Request;
86
+ };
87
+
88
+ class TPurecalcCompileService : public NActors ::TActor<TPurecalcCompileService> {
89
+ using TBase = NActors::TActor<TPurecalcCompileService>;
90
+
91
+ struct TCounters {
92
+ const NMonitoring::TDynamicCounterPtr Counters;
93
+
94
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveCompileActors;
95
+ NMonitoring::TDynamicCounters::TCounterPtr CompileQueueSize;
96
+
97
+ explicit TCounters (NMonitoring::TDynamicCounterPtr counters)
98
+ : Counters(counters)
99
+ {
100
+ Register ();
101
+ }
102
+
103
+ private:
104
+ void Register () {
105
+ ActiveCompileActors = Counters->GetCounter (" ActiveCompileActors" , false );
106
+ CompileQueueSize = Counters->GetCounter (" CompileQueueSize" , false );
107
+ }
108
+ };
109
+
110
+ public:
111
+ TPurecalcCompileService (const NConfig::TCompileServiceConfig& config, NMonitoring::TDynamicCounterPtr counters)
112
+ : TBase(&TPurecalcCompileService::StateFunc)
113
+ , Config(config)
114
+ , InFlightLimit(Config.GetParallelCompilationLimit() ? Config.GetParallelCompilationLimit() : std::numeric_limits<ui64>::max())
115
+ , LogPrefix(" TPurecalcCompileService: " )
116
+ , Counters(counters)
117
+ {}
118
+
119
+ STRICT_STFUNC (StateFunc,
120
+ hFunc (TEvRowDispatcher::TEvPurecalcCompileRequest, Handle );
121
+ hFunc (TEvRowDispatcher::TEvPurecalcCompileAbort, Handle )
122
+ hFunc(TEvPrivate::TEvCompileFinished, Handle );
123
+ )
124
+
125
+ void Handle (TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr& ev) {
126
+ const auto requestActor = ev->Sender ;
127
+ const ui64 requestId = ev->Cookie ;
128
+ LOG_ROW_DISPATCHER_TRACE (" Add to compile queue request with id " << requestId << " from " << requestActor);
129
+
130
+ // Remove old compile request
131
+ RemoveRequest (requestActor, requestId);
132
+
133
+ // Add new request
134
+ RequestsQueue.emplace_back (std::move (ev));
135
+ Y_ENSURE (RequestsIndex.emplace (std::make_pair (requestActor, requestId), --RequestsQueue.end ()).second );
136
+ Counters.CompileQueueSize ->Inc ();
137
+
138
+ StartCompilation ();
139
+ }
140
+
141
+ void Handle (TEvRowDispatcher::TEvPurecalcCompileAbort::TPtr& ev) {
142
+ LOG_ROW_DISPATCHER_TRACE (" Abort compile request with id " << ev->Cookie << " from " << ev->Sender );
143
+
144
+ RemoveRequest (ev->Sender , ev->Cookie );
145
+ }
146
+
147
+ void Handle (TEvPrivate::TEvCompileFinished::TPtr& ev) {
148
+ LOG_ROW_DISPATCHER_TRACE (" Compile finished for request with id " << ev->Get ()->RequestId << " from " << ev->Get ()->RequestActor );
149
+
150
+ InFlightCompilations.erase (ev->Sender );
151
+ Counters.ActiveCompileActors ->Dec ();
152
+
153
+ StartCompilation ();
154
+ }
155
+
156
+ private:
157
+ void RemoveRequest (NActors::TActorId requestActor, ui64 requestId) {
158
+ const auto it = RequestsIndex.find (std::make_pair (requestActor, requestId));
159
+ if (it == RequestsIndex.end ()) {
160
+ return ;
161
+ }
162
+
163
+ RequestsQueue.erase (it->second );
164
+ RequestsIndex.erase (it);
165
+ Counters.CompileQueueSize ->Dec ();
166
+ }
167
+
168
+ void StartCompilation () {
169
+ while (!RequestsQueue.empty () && InFlightCompilations.size () < InFlightLimit) {
170
+ auto request = std::move (RequestsQueue.front ());
171
+ RemoveRequest (request->Sender , request->Cookie );
172
+
173
+ const auto factory = GetOrCreateFactory (request->Get ()->Settings );
174
+ const auto compileActor = Register (new TPurecalcCompileActor (SelfId (), factory, std::move (request)));
175
+ Y_ENSURE (InFlightCompilations.emplace (compileActor).second );
176
+ Counters.ActiveCompileActors ->Inc ();
177
+ }
178
+ }
179
+
53
180
NYql::NPureCalc::IProgramFactoryPtr GetOrCreateFactory (const TPurecalcCompileSettings& settings) {
54
181
const auto it = ProgramFactories.find (settings);
55
182
if (it != ProgramFactories.end ()) {
@@ -62,15 +189,23 @@ class TPurecalcCompileService : public NActors::TActor<TPurecalcCompileService>
62
189
}
63
190
64
191
private:
192
+ const NConfig::TCompileServiceConfig Config;
193
+ const ui64 InFlightLimit;
65
194
const TString LogPrefix;
66
195
196
+ std::list<TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr> RequestsQueue;
197
+ THashMap<std::pair<NActors::TActorId, ui64>, std::list<TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr>::iterator> RequestsIndex;
198
+ std::unordered_set<NActors::TActorId> InFlightCompilations;
199
+
67
200
std::map<TPurecalcCompileSettings, NYql::NPureCalc::IProgramFactoryPtr> ProgramFactories;
201
+
202
+ const TCounters Counters;
68
203
};
69
204
70
- } // namespace {
205
+ } // anonymous namespace
71
206
72
- NActors::IActor* CreatePurecalcCompileService () {
73
- return new TPurecalcCompileService ();
207
+ NActors::IActor* CreatePurecalcCompileService (const NConfig::TCompileServiceConfig& config, NMonitoring::TDynamicCounterPtr counters ) {
208
+ return new TPurecalcCompileService (config, counters );
74
209
}
75
210
76
211
} // namespace NFq::NRowDispatcher
0 commit comments