5
5
#include " executor_pool.h"
6
6
#include " mailbox_queue_simple.h"
7
7
#include " mailbox_queue_revolving.h"
8
+ #include < functional>
8
9
#include < ydb/library/actors/util/unordered_cache.h>
9
10
#include < library/cpp/threading/queue/mpsc_htswap.h>
10
11
#include < library/cpp/threading/queue/mpsc_read_as_filled.h>
@@ -27,6 +28,10 @@ namespace NActors {
27
28
28
29
struct TMailboxHeader ;
29
30
31
+ struct TMailboxStat {
32
+ ui64 ElapsedCycles = 0 ;
33
+ };
34
+
30
35
template <bool >
31
36
struct TMailboxUsageImpl {
32
37
void Push (ui64 /* localId*/ ) {}
@@ -53,7 +58,8 @@ namespace NActors {
53
58
enum EType {
54
59
Simple = 0 ,
55
60
Array = 1 ,
56
- Map = 2
61
+ Map = 2 ,
62
+ Complex = 3 ,
57
63
};
58
64
};
59
65
@@ -91,6 +97,8 @@ namespace NActors {
91
97
TActorPair Actors[ARRAY_CAPACITY];
92
98
};
93
99
100
+ struct alignas (64 ) TComplexActorInfo;
101
+
94
102
union TActorsInfo {
95
103
TActorPair Simple;
96
104
struct {
@@ -100,11 +108,19 @@ namespace NActors {
100
108
struct {
101
109
TActorMap* ActorsMap;
102
110
} Map;
111
+ TComplexActorInfo* Complex;
103
112
} ActorsInfo;
104
113
114
+ struct alignas (64 ) TComplexActorInfo{
115
+ TActorsInfo ActorsInfo;
116
+ std::function<void (const TMailboxStat&)> StatCallback;
117
+ TMailboxActorPack::EType ActorPack;
118
+ };
119
+
105
120
TMailboxHeader (TMailboxType::EType type);
106
121
~TMailboxHeader ();
107
122
123
+ static bool CleanupActors (TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo);
108
124
bool CleanupActors ();
109
125
110
126
// this interface is used exclusively by executor thread, so implementation is there
@@ -123,7 +139,7 @@ namespace NActors {
123
139
}
124
140
125
141
template <typename T>
126
- void ForEach (T&& callback) noexcept {
142
+ static void ForEach (TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo, T&& callback) noexcept {
127
143
switch (ActorPack) {
128
144
case TMailboxActorPack::Simple:
129
145
if (ActorsInfo.Simple .ActorId ) {
@@ -143,10 +159,22 @@ namespace NActors {
143
159
callback (row.ActorId , row.Actor );
144
160
}
145
161
break ;
162
+
163
+ case TMailboxActorPack::Complex:
164
+ Y_ABORT (" Unexpected ActorPack type" );
146
165
}
147
166
}
148
167
149
- IActor* FindActor (ui64 localActorId) noexcept {
168
+ template <typename T>
169
+ void ForEach (T&& callback) noexcept {
170
+ if (ActorPack != TMailboxActorPack::Complex) {
171
+ ForEach (static_cast <TMailboxActorPack::EType>(ActorPack), ActorsInfo, std::move (callback));
172
+ } else {
173
+ ForEach (ActorsInfo.Complex ->ActorPack , ActorsInfo.Complex ->ActorsInfo , std::move (callback));
174
+ }
175
+ }
176
+
177
+ static IActor* FindActor (TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo, ui64 localActorId) noexcept {
150
178
switch (ActorPack) {
151
179
case TMailboxActorPack::Simple: {
152
180
if (ActorsInfo.Simple .ActorId == localActorId)
@@ -167,13 +195,21 @@ namespace NActors {
167
195
}
168
196
break ;
169
197
}
170
- default :
171
- Y_ABORT ();
198
+ case TMailboxActorPack::Complex :
199
+ Y_ABORT (" Unexpected ActorPack type " );
172
200
}
173
201
return nullptr ;
174
202
}
175
203
176
- void AttachActor (ui64 localActorId, IActor* actor) noexcept {
204
+ IActor* FindActor (ui64 localActorId) noexcept {
205
+ if (ActorPack != TMailboxActorPack::Complex) {
206
+ return FindActor (static_cast <TMailboxActorPack::EType>(ActorPack), ActorsInfo, localActorId);
207
+ } else {
208
+ return FindActor (ActorsInfo.Complex ->ActorPack , ActorsInfo.Complex ->ActorsInfo , localActorId);
209
+ }
210
+ }
211
+
212
+ static void AttachActor (TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo, ui64 localActorId, IActor* actor) noexcept {
177
213
switch (ActorPack) {
178
214
case TMailboxActorPack::Simple: {
179
215
if (ActorsInfo.Simple .ActorId == 0 ) {
@@ -210,13 +246,21 @@ namespace NActors {
210
246
}
211
247
break ;
212
248
}
213
- default :
214
- Y_ABORT ();
249
+ case TMailboxActorPack::Complex :
250
+ Y_ABORT (" Unexpected ActorPack type " );
215
251
}
216
252
}
217
253
218
- IActor* DetachActor (ui64 localActorId) noexcept {
219
- Y_DEBUG_ABORT_UNLESS (FindActor (localActorId) != nullptr );
254
+ void AttachActor (ui64 localActorId, IActor* actor) noexcept {
255
+ if (ActorPack != TMailboxActorPack::Complex) {
256
+ AttachActor (static_cast <TMailboxActorPack::EType>(ActorPack), ActorsInfo, localActorId, actor);
257
+ } else {
258
+ AttachActor (ActorsInfo.Complex ->ActorPack , ActorsInfo.Complex ->ActorsInfo , localActorId, actor);
259
+ }
260
+ }
261
+
262
+ static IActor* DetachActor (TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo, ui64 localActorId) noexcept {
263
+ Y_DEBUG_ABORT_UNLESS (FindActor (ActorPack, ActorsInfo, localActorId) != nullptr );
220
264
221
265
IActor* actorToDestruct = nullptr ;
222
266
@@ -270,11 +314,36 @@ namespace NActors {
270
314
}
271
315
break ;
272
316
}
317
+ case TMailboxActorPack::Complex:
318
+ Y_ABORT (" Unexpected ActorPack type" );
273
319
}
274
320
275
321
return actorToDestruct;
276
322
}
277
323
324
+ IActor* DetachActor (ui64 localActorId) noexcept {
325
+ if (ActorPack != TMailboxActorPack::Complex) {
326
+ return DetachActor (static_cast <TMailboxActorPack::EType>(ActorPack), ActorsInfo, localActorId);
327
+ } else {
328
+ return DetachActor (ActorsInfo.Complex ->ActorPack , ActorsInfo.Complex ->ActorsInfo , localActorId);
329
+ }
330
+ }
331
+
332
+ void SetStatCallback (std::function<void (const TMailboxStat&)> callback) {
333
+ TComplexActorInfo* complex = new TComplexActorInfo;
334
+ complex->StatCallback = callback;
335
+ complex->ActorPack = static_cast <TMailboxActorPack::EType>(ActorPack);
336
+ complex->ActorsInfo = ActorsInfo;
337
+ ActorPack = TMailboxActorPack::Complex;
338
+ ActorsInfo.Complex = complex;
339
+ }
340
+
341
+ void InvokeMailboxStat (const TMailboxStat &stat) {
342
+ if (ActorPack == TMailboxActorPack::Complex) {
343
+ ActorsInfo.Complex ->StatCallback (stat);
344
+ }
345
+ }
346
+
278
347
std::pair<ui32, ui32> CountMailboxEvents (ui64 localActorId, ui32 maxTraverse);
279
348
};
280
349
0 commit comments