@@ -577,7 +577,7 @@ void TPartition::InitComplete(const TActorContext& ctx) {
577
577
TabletCounters.Percentile ()[COUNTER_LATENCY_PQ_INIT].IncrementFor (InitDuration.MilliSeconds ());
578
578
579
579
FillReadFromTimestamps (ctx);
580
- ResendPendingEvents (ctx);
580
+ ProcessPendingEvents (ctx);
581
581
ProcessTxsAndUserActs (ctx);
582
582
583
583
ctx.Send (ctx.SelfID , new TEvents::TEvWakeup ());
@@ -951,37 +951,69 @@ void TPartition::Handle(TEvPersQueue::TEvProposeTransaction::TPtr& ev, const TAc
951
951
ProcessTxsAndUserActs (ctx);
952
952
}
953
953
954
+ template <class T >
955
+ void TPartition::ProcessPendingEvent (TAutoPtr<TEventHandle<T>>& ev, const TActorContext& ctx)
956
+ {
957
+ if (PendingEvents.empty ()) {
958
+ // Optimization: if the queue is empty, you can process the message immediately
959
+ ProcessPendingEvent (std::unique_ptr<T>(ev->Release ().Release ()), ctx);
960
+ } else {
961
+ // We need to keep the order in which the messages arrived
962
+ AddPendingEvent (ev);
963
+ ProcessPendingEvents (ctx);
964
+ }
965
+ }
966
+
967
+ template <>
968
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvProposePartitionConfig> ev, const TActorContext& ctx)
969
+ {
970
+ PushBackDistrTx (ev.release ());
971
+
972
+ ProcessTxsAndUserActs (ctx);
973
+ }
974
+
954
975
void TPartition::Handle (TEvPQ::TEvProposePartitionConfig::TPtr& ev, const TActorContext& ctx)
955
976
{
956
977
PQ_LOG_D (" Handle TEvPQ::TEvProposePartitionConfig" <<
957
978
" Step " << ev->Get ()->Step <<
958
979
" , TxId " << ev->Get ()->TxId );
959
980
960
- PushBackDistrTx (ev->Release ());
981
+ ProcessPendingEvent (ev, ctx);
982
+ }
961
983
962
- ProcessTxsAndUserActs (ctx);
984
+ template <class T >
985
+ void TPartition::AddPendingEvent (TAutoPtr<TEventHandle<T>>& ev)
986
+ {
987
+ std::unique_ptr<T> p (ev->Release ().Release ());
988
+ PendingEvents.emplace_back (std::move (p));
963
989
}
964
990
965
991
void TPartition::HandleOnInit (TEvPQ::TEvTxCalcPredicate::TPtr& ev, const TActorContext&)
966
992
{
967
993
PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxCalcPredicate" );
968
994
969
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
995
+ AddPendingEvent (ev);
970
996
}
971
997
972
998
void TPartition::HandleOnInit (TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext&)
973
999
{
974
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1000
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxCommit" );
1001
+
1002
+ AddPendingEvent (ev);
975
1003
}
976
1004
977
1005
void TPartition::HandleOnInit (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext&)
978
1006
{
979
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1007
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxRollback" );
1008
+
1009
+ AddPendingEvent (ev);
980
1010
}
981
1011
982
1012
void TPartition::HandleOnInit (TEvPQ::TEvProposePartitionConfig::TPtr& ev, const TActorContext&)
983
1013
{
984
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1014
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvProposePartitionConfig" );
1015
+
1016
+ AddPendingEvent (ev);
985
1017
}
986
1018
987
1019
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext&)
@@ -991,7 +1023,7 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TAc
991
1023
Y_ABORT_UNLESS (IsSupportive ());
992
1024
993
1025
ev->Get ()->OriginalPartition = ev->Sender ;
994
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1026
+ AddPendingEvent (ev);
995
1027
}
996
1028
997
1029
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TActorContext&)
@@ -1000,7 +1032,7 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TA
1000
1032
1001
1033
Y_ABORT_UNLESS (!IsSupportive ());
1002
1034
1003
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1035
+ AddPendingEvent (ev);
1004
1036
}
1005
1037
1006
1038
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActorContext&)
@@ -1009,43 +1041,46 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActo
1009
1041
1010
1042
Y_ABORT_UNLESS (!IsSupportive ());
1011
1043
1012
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1044
+ AddPendingEvent (ev);
1013
1045
}
1014
1046
1015
- void TPartition::Handle (TEvPQ::TEvTxCalcPredicate::TPtr& ev, const TActorContext& ctx)
1047
+ template <>
1048
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxCalcPredicate> ev, const TActorContext& ctx)
1016
1049
{
1017
- PQ_LOG_D (" Handle TEvPQ::TEvTxCalcPredicate" <<
1018
- " Step " << ev->Get ()->Step <<
1019
- " , TxId " << ev->Get ()->TxId );
1020
-
1021
1050
if (PlanStep.Defined () && TxId.Defined ()) {
1022
- if (GetStepAndTxId (*ev-> Get () ) < GetStepAndTxId (*PlanStep, *TxId)) {
1051
+ if (GetStepAndTxId (*ev) < GetStepAndTxId (*PlanStep, *TxId)) {
1023
1052
Send (Tablet,
1024
- MakeHolder<TEvPQ::TEvTxCalcPredicateResult>(ev->Get ()-> Step ,
1025
- ev->Get ()-> TxId ,
1053
+ MakeHolder<TEvPQ::TEvTxCalcPredicateResult>(ev->Step ,
1054
+ ev->TxId ,
1026
1055
Partition,
1027
1056
Nothing ()).Release ());
1028
1057
return ;
1029
1058
}
1030
1059
}
1031
1060
1032
- PushBackDistrTx (ev-> Release ());
1061
+ PushBackDistrTx (ev. release ());
1033
1062
1034
1063
ProcessTxsAndUserActs (ctx);
1035
1064
}
1036
1065
1037
- void TPartition::Handle (TEvPQ::TEvTxCommit ::TPtr& ev, const TActorContext& ctx)
1066
+ void TPartition::Handle (TEvPQ::TEvTxCalcPredicate ::TPtr& ev, const TActorContext& ctx)
1038
1067
{
1039
- PQ_LOG_D (" Handle TEvPQ::TEvTxCommit " <<
1068
+ PQ_LOG_D (" Handle TEvPQ::TEvTxCalcPredicate " <<
1040
1069
" Step " << ev->Get ()->Step <<
1041
1070
" , TxId " << ev->Get ()->TxId );
1042
1071
1072
+ ProcessPendingEvent (ev, ctx);
1073
+ }
1074
+
1075
+ template <>
1076
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxCommit> ev, const TActorContext& ctx)
1077
+ {
1043
1078
if (PlanStep.Defined () && TxId.Defined ()) {
1044
- if (GetStepAndTxId (*ev-> Get () ) < GetStepAndTxId (*PlanStep, *TxId)) {
1079
+ if (GetStepAndTxId (*ev) < GetStepAndTxId (*PlanStep, *TxId)) {
1045
1080
PQ_LOG_D (" Send TEvTxCommitDone" <<
1046
- " Step " << ev->Get ()-> Step <<
1047
- " , TxId " << ev->Get ()-> TxId );
1048
- ctx.Send (Tablet, MakeCommitDone (ev->Get ()-> Step , ev-> Get () ->TxId ).Release ());
1081
+ " Step " << ev->Step <<
1082
+ " , TxId " << ev->TxId );
1083
+ ctx.Send (Tablet, MakeCommitDone (ev->Step , ev->TxId ).Release ());
1049
1084
return ;
1050
1085
}
1051
1086
}
@@ -1055,32 +1090,42 @@ void TPartition::Handle(TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext& ctx)
1055
1090
Y_ABORT_UNLESS (TransactionsInflight.size () == 1 ,
1056
1091
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1057
1092
TabletID, Partition.OriginalPartitionId ,
1058
- ev->Get ()->Step , ev->Get ()->TxId );
1093
+ ev->Step , ev->TxId );
1094
+ PendingExplicitMessageGroups = ev->ExplicitMessageGroups ;
1059
1095
} else {
1060
1096
Y_ABORT_UNLESS (!TransactionsInflight.empty (),
1061
1097
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1062
1098
TabletID, Partition.OriginalPartitionId ,
1063
- ev->Get ()-> Step , ev-> Get () ->TxId );
1064
- txIter = TransactionsInflight.find (ev->Get ()-> TxId );
1099
+ ev->Step , ev->TxId );
1100
+ txIter = TransactionsInflight.find (ev->TxId );
1065
1101
Y_ABORT_UNLESS (!txIter.IsEnd (),
1066
1102
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1067
1103
TabletID, Partition.OriginalPartitionId ,
1068
- ev->Get ()-> Step , ev-> Get () ->TxId );
1104
+ ev->Step , ev->TxId );
1069
1105
}
1070
1106
Y_ABORT_UNLESS (txIter->second ->State == ECommitState::Pending);
1071
1107
1072
1108
txIter->second ->State = ECommitState::Committed;
1073
1109
ProcessTxsAndUserActs (ctx);
1074
1110
}
1075
1111
1076
- void TPartition::Handle (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx)
1112
+ void TPartition::Handle (TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext& ctx)
1113
+ {
1114
+ PQ_LOG_D (" Handle TEvPQ::TEvTxCommit" <<
1115
+ " Step " << ev->Get ()->Step <<
1116
+ " , TxId " << ev->Get ()->TxId );
1117
+
1118
+ ProcessPendingEvent (ev, ctx);
1119
+ }
1120
+
1121
+ template <>
1122
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxRollback> ev, const TActorContext& ctx)
1077
1123
{
1078
- auto * event = ev->Get ();
1079
1124
if (PlanStep.Defined () && TxId.Defined ()) {
1080
- if (GetStepAndTxId (*event ) < GetStepAndTxId (*PlanStep, *TxId)) {
1125
+ if (GetStepAndTxId (*ev ) < GetStepAndTxId (*PlanStep, *TxId)) {
1081
1126
PQ_LOG_D (" Rollback for" <<
1082
- " Step " << ev->Get ()-> Step <<
1083
- " , TxId " << ev->Get ()-> TxId );
1127
+ " Step " << ev->Step <<
1128
+ " , TxId " << ev->TxId );
1084
1129
return ;
1085
1130
}
1086
1131
}
@@ -1094,7 +1139,7 @@ void TPartition::Handle(TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx
1094
1139
Y_ABORT_UNLESS (!TransactionsInflight.empty (),
1095
1140
" PQ: %" PRIu64 " , Partition: %" PRIu32,
1096
1141
TabletID, Partition.OriginalPartitionId );
1097
- txIter = TransactionsInflight.find (ev->Get ()-> TxId );
1142
+ txIter = TransactionsInflight.find (ev->TxId );
1098
1143
Y_ABORT_UNLESS (!txIter.IsEnd (),
1099
1144
" PQ: %" PRIu64 " , Partition: %" PRIu32,
1100
1145
TabletID, Partition.OriginalPartitionId );
@@ -1105,13 +1150,17 @@ void TPartition::Handle(TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx
1105
1150
ProcessTxsAndUserActs (ctx);
1106
1151
}
1107
1152
1108
- void TPartition::Handle (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext& ctx) {
1109
- PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoRequest" );
1110
- TActorId originalPartition = ev->Get ()->OriginalPartition ;
1111
- if (!originalPartition) {
1112
- // original message
1113
- originalPartition = ev->Sender ;
1114
- }
1153
+ void TPartition::Handle (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx)
1154
+ {
1155
+ ProcessPendingEvent (ev, ctx);
1156
+ }
1157
+
1158
+ template <>
1159
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoRequest> ev, const TActorContext& ctx)
1160
+ {
1161
+ TActorId originalPartition = ev->OriginalPartition ;
1162
+ Y_ABORT_UNLESS (originalPartition != TActorId ());
1163
+
1115
1164
if (ClosedInternalPartition || WaitingForPreviousBlobQuota () || (CurrentStateFunc () != &TThis::StateIdle)) {
1116
1165
PQ_LOG_D (" Send TEvPQ::TEvGetWriteInfoError" );
1117
1166
auto * response = new TEvPQ::TEvGetWriteInfoError (Partition.InternalPartitionId ,
@@ -1143,6 +1192,14 @@ void TPartition::Handle(TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorCon
1143
1192
ctx.Send (originalPartition, response);
1144
1193
}
1145
1194
1195
+ void TPartition::Handle (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext& ctx) {
1196
+ PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoRequest" );
1197
+
1198
+ ev->Get ()->OriginalPartition = ev->Sender ;
1199
+
1200
+ ProcessPendingEvent (ev, ctx);
1201
+ }
1202
+
1146
1203
void TPartition::WriteInfoResponseHandler (
1147
1204
const TActorId& sender,
1148
1205
TGetWriteInfoResp&& ev,
@@ -1231,17 +1288,36 @@ TPartition::EProcessResult TPartition::ApplyWriteInfoResponse(TTransaction& tx)
1231
1288
return ret;
1232
1289
}
1233
1290
1291
+ template <>
1292
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoResponse> ev, const TActorContext& ctx)
1293
+ {
1294
+ const auto sender = ev->SupportivePartition ;
1295
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1296
+ }
1297
+
1234
1298
void TPartition::Handle (TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TActorContext& ctx) {
1235
1299
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoResponse" );
1236
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1300
+
1301
+ ev->Get ()->SupportivePartition = ev->Sender ;
1302
+
1303
+ ProcessPendingEvent (ev, ctx);
1237
1304
}
1238
1305
1306
+ template <>
1307
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoError> ev, const TActorContext& ctx)
1308
+ {
1309
+ const auto sender = ev->SupportivePartition ;
1310
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1311
+ }
1239
1312
1240
1313
void TPartition::Handle (TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActorContext& ctx) {
1241
1314
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoError " <<
1242
1315
" Cookie " << ev->Get ()->Cookie <<
1243
1316
" , Message " << ev->Get ()->Message );
1244
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1317
+
1318
+ ev->Get ()->SupportivePartition = ev->Sender ;
1319
+
1320
+ ProcessPendingEvent (ev, ctx);
1245
1321
}
1246
1322
1247
1323
void TPartition::ReplyToProposeOrPredicate (TSimpleSharedPtr<TTransaction>& tx, bool isPredicate) {
@@ -2619,16 +2695,6 @@ void TPartition::ChangePlanStepAndTxId(ui64 step, ui64 txId)
2619
2695
TxIdHasChanged = true ;
2620
2696
}
2621
2697
2622
- void TPartition::ResendPendingEvents (const TActorContext& ctx)
2623
- {
2624
- PQ_LOG_D (" Resend pending events. Count " << PendingEvents.size ());
2625
-
2626
- while (!PendingEvents.empty ()) {
2627
- ctx.Schedule (TDuration::Zero (), PendingEvents.front ().release ());
2628
- PendingEvents.pop_front ();
2629
- }
2630
- }
2631
-
2632
2698
TPartition::EProcessResult TPartition::PreProcessImmediateTx (const NKikimrPQ::TEvProposeTransaction& tx)
2633
2699
{
2634
2700
if (AffectedUsers.size () >= MAX_USERS) {
@@ -3495,14 +3561,17 @@ void TPartition::Handle(TEvPQ::TEvCheckPartitionStatusRequest::TPtr& ev, const T
3495
3561
3496
3562
void TPartition::HandleOnInit (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext&)
3497
3563
{
3564
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvDeletePartition" );
3565
+
3498
3566
Y_ABORT_UNLESS (IsSupportive ());
3499
3567
3500
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
3568
+ AddPendingEvent (ev);
3501
3569
}
3502
3570
3503
- void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& ctx)
3571
+ template <>
3572
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvDeletePartition> ev, const TActorContext& ctx)
3504
3573
{
3505
- PQ_LOG_D ( " Handle TEvPQ::TEvDeletePartition " );
3574
+ Y_UNUSED (ev );
3506
3575
3507
3576
Y_ABORT_UNLESS (IsSupportive ());
3508
3577
Y_ABORT_UNLESS (DeletePartitionState == DELETION_NOT_INITED);
@@ -3512,6 +3581,13 @@ void TPartition::Handle(TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& c
3512
3581
ProcessTxsAndUserActs (ctx);
3513
3582
}
3514
3583
3584
+ void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext& ctx)
3585
+ {
3586
+ PQ_LOG_D (" Handle TEvPQ::TEvDeletePartition" );
3587
+
3588
+ ProcessPendingEvent (ev, ctx);
3589
+ }
3590
+
3515
3591
void TPartition::ScheduleNegativeReplies ()
3516
3592
{
3517
3593
auto processQueue = [&](std::deque<TUserActionAndTransactionEvent>& queue) {
@@ -3582,6 +3658,23 @@ void TPartition::ScheduleTransactionCompleted(const NKikimrPQ::TEvProposeTransac
3582
3658
MakeHolder<TEvPQ::TEvTransactionCompleted>(writeId).Release ());
3583
3659
}
3584
3660
3661
+ void TPartition::ProcessPendingEvents (const TActorContext& ctx)
3662
+ {
3663
+ PQ_LOG_D (" Process pending events. Count " << PendingEvents.size ());
3664
+
3665
+ while (!PendingEvents.empty ()) {
3666
+ auto ev = std::move (PendingEvents.front ());
3667
+ PendingEvents.pop_front ();
3668
+
3669
+ auto visitor = [this , &ctx](auto && v) {
3670
+ using T = std::decay_t <decltype (v)>;
3671
+ ProcessPendingEvent (std::forward<T>(v), ctx);
3672
+ };
3673
+
3674
+ std::visit (visitor, std::move (ev));
3675
+ }
3676
+ }
3677
+
3585
3678
const NKikimrPQ::TPQTabletConfig::TPartition* TPartition::GetPartitionConfig (const NKikimrPQ::TPQTabletConfig& config)
3586
3679
{
3587
3680
return NPQ::GetPartitionConfig (config, Partition.OriginalPartitionId );
0 commit comments