@@ -181,6 +181,26 @@ namespace NActors {
181181 SafeTypeName (actorType));
182182 }
183183
184+ ui32 TGenericExecutorThread::GetOverwrittenEventsPerMailbox () const {
185+ return Ctx.OverwrittenEventsPerMailbox ;
186+ }
187+
188+ void TGenericExecutorThread::SetOverwrittenEventsPerMailbox (ui32 value) {
189+ Ctx.OverwrittenEventsPerMailbox = Max (value, Ctx.EventsPerMailbox );
190+ }
191+
192+ ui64 TGenericExecutorThread::GetOverwrittenTimePerMailboxTs () const {
193+ return Ctx.OverwrittenTimePerMailboxTs ;
194+ }
195+
196+ void TGenericExecutorThread::SetOverwrittenTimePerMailboxTs (ui64 value) {
197+ Ctx.OverwrittenTimePerMailboxTs = Max (value, Ctx.TimePerMailboxTs );
198+ }
199+
200+ void TGenericExecutorThread::SubscribeToPreemption (TActorId actorId) {
201+ Ctx.PreemptionSubscribed .push_back (actorId);
202+ }
203+
184204 TGenericExecutorThread::TProcessingResult TGenericExecutorThread::Execute (TMailbox* mailbox, bool isTailExecution) {
185205 Y_DEBUG_ABORT_UNLESS (DyingActors.empty ());
186206
@@ -194,16 +214,20 @@ namespace NActors {
194214 ui32 prevActivityType = std::numeric_limits<ui32>::max ();
195215 TActorId recipient;
196216 bool firstEvent = true ;
197- bool preempted = false ;
217+ bool preemptedByEventCount = false ;
218+ bool preemptedByCycles = false ;
219+ bool preemptedByTailSend = false ;
198220 bool wasWorking = false ;
199221 NHPTimer::STime hpnow = Ctx.HPStart ;
200222 NHPTimer::STime hpprev = TlsThreadContext->UpdateStartOfProcessingEventTS (hpnow);
201223 Ctx.AddElapsedCycles (ActorSystemIndex, hpnow - hpprev);
202224 NHPTimer::STime eventStart = Ctx.HPStart ;
203225 TlsThreadContext->ActivationStartTS .store (Ctx.HPStart , std::memory_order_release);
204226
227+ Ctx.OverwrittenEventsPerMailbox = Ctx.EventsPerMailbox ;
228+ Ctx.OverwrittenTimePerMailboxTs = Ctx.TimePerMailboxTs ;
205229 bool drained = false ;
206- for (; Ctx.ExecutedEvents < Ctx.EventsPerMailbox ; ++Ctx.ExecutedEvents ) {
230+ for (; Ctx.ExecutedEvents < Ctx.OverwrittenEventsPerMailbox ; ++Ctx.ExecutedEvents ) {
207231 if (TAutoPtr<IEventHandle> evExt = mailbox->Pop ()) {
208232 recipient = evExt->GetRecipientRewrite ();
209233 TActorContext ctx (*mailbox, *this , eventStart, recipient);
@@ -302,6 +326,7 @@ namespace NActors {
302326 Ctx.WorkerId ,
303327 recipient.ToString (),
304328 SafeTypeName (actorType));
329+ preemptedByTailSend = true ;
305330 break ;
306331 }
307332
@@ -317,7 +342,7 @@ namespace NActors {
317342 Ctx.WorkerId ,
318343 recipient.ToString (),
319344 SafeTypeName (actorType));
320- preempted = true ;
345+ preemptedByCycles = true ;
321346 break ;
322347 }
323348
@@ -333,7 +358,7 @@ namespace NActors {
333358 Ctx.WorkerId ,
334359 recipient.ToString (),
335360 SafeTypeName (actorType));
336- preempted = true ;
361+ preemptedByCycles = true ;
337362 break ;
338363 }
339364
@@ -348,7 +373,7 @@ namespace NActors {
348373 Ctx.WorkerId ,
349374 recipient.ToString (),
350375 SafeTypeName (actorType));
351- preempted = true ;
376+ preemptedByEventCount = true ;
352377 break ;
353378 }
354379 } else {
@@ -367,6 +392,22 @@ namespace NActors {
367392 break ; // empty queue, leave
368393 }
369394 }
395+ if (Ctx.PreemptionSubscribed .size ()) {
396+ std::unique_ptr<TEvents::TEvPreemption> event = std::make_unique<TEvents::TEvPreemption>();
397+ event->ByEventCount = preemptedByEventCount;
398+ event->ByCycles = preemptedByCycles;
399+ event->ByTailSend = preemptedByTailSend;
400+ event->EventCount = Ctx.ExecutedEvents ;
401+ event->Cycles = hpnow - Ctx.HPStart ;
402+ TAutoPtr<IEventHandle> ev = new IEventHandle (TActorId (), TActorId (), event.release ());
403+ for (const auto & actorId : Ctx.PreemptionSubscribed ) {
404+ IActor *actor = mailbox->FindActor (actorId.LocalId ());
405+ if (actor) {
406+ actor->Receive (ev);
407+ }
408+ }
409+ Ctx.PreemptionSubscribed .clear ();
410+ }
370411 TlsThreadContext->ActivationStartTS .store (hpnow, std::memory_order_release);
371412 TlsThreadContext->ElapsingActorActivity .store (ActorSystemIndex, std::memory_order_release);
372413
@@ -378,7 +419,7 @@ namespace NActors {
378419 } else {
379420 mailbox->Unlock (Ctx.Executor , hpnow, RevolvingWriteCounter);
380421 }
381- return {preempted , wasWorking};
422+ return {preemptedByEventCount || preemptedByCycles , wasWorking};
382423 }
383424
384425 TThreadId TGenericExecutorThread::GetThreadId () const {
0 commit comments