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,49 @@ 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
+ static constexpr char ActorName[] = " FQ_ROW_DISPATCHER_COMPILE_ACTOR" ;
27
47
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 );
48
+ void Bootstrap () {
49
+ Y_DEFER {
50
+ Finish ();
51
+ };
52
+
53
+ LOG_ROW_DISPATCHER_TRACE (" Started compile request" );
54
+ IProgramHolder::TPtr programHolder = std::move (Request->Get ()->ProgramHolder );
31
55
32
56
TStatus status = TStatus::Success ();
33
57
try {
34
- programHolder->CreateProgram (GetOrCreateFactory (ev-> Get ()-> Settings ) );
58
+ programHolder->CreateProgram (Factory );
35
59
} catch (const NYql::NPureCalc::TCompileError& error) {
36
60
status = TStatus::Fail (EStatusId::INTERNAL_ERROR, TStringBuilder () << " Compile issues: " << error.GetIssues ())
37
61
.AddIssue (TStringBuilder () << " Final yql: " << error.GetYql ())
@@ -41,15 +65,122 @@ class TPurecalcCompileService : public NActors::TActor<TPurecalcCompileService>
41
65
}
42
66
43
67
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 );
68
+ LOG_ROW_DISPATCHER_ERROR (" Compilation failed for request" );
69
+ Send (Request ->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (status.GetStatus (), status.GetErrorDescription ()), 0 , Request ->Cookie );
46
70
} 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 );
71
+ LOG_ROW_DISPATCHER_TRACE (" Compilation completed for request" );
72
+ Send (Request->Sender , new TEvRowDispatcher::TEvPurecalcCompileResponse (std::move (programHolder)), 0 , Request->Cookie );
73
+ }
74
+ }
75
+
76
+ private:
77
+ void Finish () {
78
+ Send (Owner, new TEvPrivate::TEvCompileFinished (Request->Sender , Request->Cookie ));
79
+ PassAway ();
80
+ }
81
+
82
+ private:
83
+ const NActors::TActorId Owner;
84
+ const NYql::NPureCalc::IProgramFactoryPtr Factory;
85
+ const TString LogPrefix;
86
+
87
+ TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr Request;
88
+ };
89
+
90
+ class TPurecalcCompileService : public NActors ::TActor<TPurecalcCompileService> {
91
+ using TBase = NActors::TActor<TPurecalcCompileService>;
92
+
93
+ struct TCounters {
94
+ const NMonitoring::TDynamicCounterPtr Counters;
95
+
96
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveCompileActors;
97
+ NMonitoring::TDynamicCounters::TCounterPtr CompileQueueSize;
98
+
99
+ explicit TCounters (NMonitoring::TDynamicCounterPtr counters)
100
+ : Counters(counters)
101
+ {
102
+ Register ();
49
103
}
104
+
105
+ private:
106
+ void Register () {
107
+ ActiveCompileActors = Counters->GetCounter (" ActiveCompileActors" , false );
108
+ CompileQueueSize = Counters->GetCounter (" CompileQueueSize" , false );
109
+ }
110
+ };
111
+
112
+ public:
113
+ TPurecalcCompileService (const NConfig::TCompileServiceConfig& config, NMonitoring::TDynamicCounterPtr counters)
114
+ : TBase(&TPurecalcCompileService::StateFunc)
115
+ , Config(config)
116
+ , InFlightLimit(Config.GetParallelCompilationLimit() ? Config.GetParallelCompilationLimit() : 1 )
117
+ , LogPrefix(" TPurecalcCompileService: " )
118
+ , Counters(counters)
119
+ {}
120
+
121
+ static constexpr char ActorName[] = " FQ_ROW_DISPATCHER_COMPILE_SERVICE" ;
122
+
123
+ STRICT_STFUNC (StateFunc,
124
+ hFunc (TEvRowDispatcher::TEvPurecalcCompileRequest, Handle );
125
+ hFunc (TEvRowDispatcher::TEvPurecalcCompileAbort, Handle )
126
+ hFunc(TEvPrivate::TEvCompileFinished, Handle );
127
+ )
128
+
129
+ void Handle (TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr& ev) {
130
+ const auto requestActor = ev->Sender ;
131
+ const ui64 requestId = ev->Cookie ;
132
+ LOG_ROW_DISPATCHER_TRACE (" Add to compile queue request with id " << requestId << " from " << requestActor);
133
+
134
+ // Remove old compile request
135
+ RemoveRequest (requestActor, requestId);
136
+
137
+ // Add new request
138
+ RequestsQueue.emplace_back (std::move (ev));
139
+ Y_ENSURE (RequestsIndex.emplace (std::make_pair (requestActor, requestId), --RequestsQueue.end ()).second );
140
+ Counters.CompileQueueSize ->Inc ();
141
+
142
+ StartCompilation ();
143
+ }
144
+
145
+ void Handle (TEvRowDispatcher::TEvPurecalcCompileAbort::TPtr& ev) {
146
+ LOG_ROW_DISPATCHER_TRACE (" Abort compile request with id " << ev->Cookie << " from " << ev->Sender );
147
+
148
+ RemoveRequest (ev->Sender , ev->Cookie );
149
+ }
150
+
151
+ void Handle (TEvPrivate::TEvCompileFinished::TPtr& ev) {
152
+ LOG_ROW_DISPATCHER_TRACE (" Compile finished for request with id " << ev->Get ()->RequestId << " from " << ev->Get ()->RequestActor );
153
+
154
+ InFlightCompilations.erase (ev->Sender );
155
+ Counters.ActiveCompileActors ->Dec ();
156
+
157
+ StartCompilation ();
50
158
}
51
159
52
160
private:
161
+ void RemoveRequest (NActors::TActorId requestActor, ui64 requestId) {
162
+ const auto it = RequestsIndex.find (std::make_pair (requestActor, requestId));
163
+ if (it == RequestsIndex.end ()) {
164
+ return ;
165
+ }
166
+
167
+ RequestsQueue.erase (it->second );
168
+ RequestsIndex.erase (it);
169
+ Counters.CompileQueueSize ->Dec ();
170
+ }
171
+
172
+ void StartCompilation () {
173
+ while (!RequestsQueue.empty () && InFlightCompilations.size () < InFlightLimit) {
174
+ auto request = std::move (RequestsQueue.front ());
175
+ RemoveRequest (request->Sender , request->Cookie );
176
+
177
+ const auto factory = GetOrCreateFactory (request->Get ()->Settings );
178
+ const auto compileActor = Register (new TPurecalcCompileActor (SelfId (), factory, std::move (request)));
179
+ Y_ENSURE (InFlightCompilations.emplace (compileActor).second );
180
+ Counters.ActiveCompileActors ->Inc ();
181
+ }
182
+ }
183
+
53
184
NYql::NPureCalc::IProgramFactoryPtr GetOrCreateFactory (const TPurecalcCompileSettings& settings) {
54
185
const auto it = ProgramFactories.find (settings);
55
186
if (it != ProgramFactories.end ()) {
@@ -62,15 +193,23 @@ class TPurecalcCompileService : public NActors::TActor<TPurecalcCompileService>
62
193
}
63
194
64
195
private:
196
+ const NConfig::TCompileServiceConfig Config;
197
+ const ui64 InFlightLimit;
65
198
const TString LogPrefix;
66
199
200
+ std::list<TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr> RequestsQueue;
201
+ THashMap<std::pair<NActors::TActorId, ui64>, std::list<TEvRowDispatcher::TEvPurecalcCompileRequest::TPtr>::iterator> RequestsIndex;
202
+ std::unordered_set<NActors::TActorId> InFlightCompilations;
203
+
67
204
std::map<TPurecalcCompileSettings, NYql::NPureCalc::IProgramFactoryPtr> ProgramFactories;
205
+
206
+ const TCounters Counters;
68
207
};
69
208
70
- } // namespace {
209
+ } // anonymous namespace
71
210
72
- NActors::IActor* CreatePurecalcCompileService () {
73
- return new TPurecalcCompileService ();
211
+ NActors::IActor* CreatePurecalcCompileService (const NConfig::TCompileServiceConfig& config, NMonitoring::TDynamicCounterPtr counters ) {
212
+ return new TPurecalcCompileService (config, counters );
74
213
}
75
214
76
215
} // namespace NFq::NRowDispatcher
0 commit comments