@@ -581,7 +581,7 @@ void TPartition::InitComplete(const TActorContext& ctx) {
581
581
TabletCounters.Percentile ()[COUNTER_LATENCY_PQ_INIT].IncrementFor (InitDuration.MilliSeconds ());
582
582
583
583
FillReadFromTimestamps (ctx);
584
- ResendPendingEvents (ctx);
584
+ ProcessPendingEvents (ctx);
585
585
ProcessTxsAndUserActs (ctx);
586
586
587
587
ctx.Send (ctx.SelfID , new TEvents::TEvWakeup ());
@@ -969,37 +969,69 @@ void TPartition::Handle(TEvPersQueue::TEvProposeTransaction::TPtr& ev, const TAc
969
969
ProcessTxsAndUserActs (ctx);
970
970
}
971
971
972
+ template <class T >
973
+ void TPartition::ProcessPendingEvent (TAutoPtr<TEventHandle<T>>& ev, const TActorContext& ctx)
974
+ {
975
+ if (PendingEvents.empty ()) {
976
+ // Optimization: if the queue is empty, you can process the message immediately
977
+ ProcessPendingEvent (std::unique_ptr<T>(ev->Release ().Release ()), ctx);
978
+ } else {
979
+ // We need to keep the order in which the messages arrived
980
+ AddPendingEvent (ev);
981
+ ProcessPendingEvents (ctx);
982
+ }
983
+ }
984
+
985
+ template <>
986
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvProposePartitionConfig> ev, const TActorContext& ctx)
987
+ {
988
+ PushBackDistrTx (ev.release ());
989
+
990
+ ProcessTxsAndUserActs (ctx);
991
+ }
992
+
972
993
void TPartition::Handle (TEvPQ::TEvProposePartitionConfig::TPtr& ev, const TActorContext& ctx)
973
994
{
974
995
PQ_LOG_D (" Handle TEvPQ::TEvProposePartitionConfig" <<
975
996
" Step " << ev->Get ()->Step <<
976
997
" , TxId " << ev->Get ()->TxId );
977
998
978
- PushBackDistrTx (ev->Release ());
999
+ ProcessPendingEvent (ev, ctx);
1000
+ }
979
1001
980
- ProcessTxsAndUserActs (ctx);
1002
+ template <class T >
1003
+ void TPartition::AddPendingEvent (TAutoPtr<TEventHandle<T>>& ev)
1004
+ {
1005
+ std::unique_ptr<T> p (ev->Release ().Release ());
1006
+ PendingEvents.emplace_back (std::move (p));
981
1007
}
982
1008
983
1009
void TPartition::HandleOnInit (TEvPQ::TEvTxCalcPredicate::TPtr& ev, const TActorContext&)
984
1010
{
985
1011
PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxCalcPredicate" );
986
1012
987
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1013
+ AddPendingEvent (ev);
988
1014
}
989
1015
990
1016
void TPartition::HandleOnInit (TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext&)
991
1017
{
992
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1018
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxCommit" );
1019
+
1020
+ AddPendingEvent (ev);
993
1021
}
994
1022
995
1023
void TPartition::HandleOnInit (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext&)
996
1024
{
997
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1025
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvTxRollback" );
1026
+
1027
+ AddPendingEvent (ev);
998
1028
}
999
1029
1000
1030
void TPartition::HandleOnInit (TEvPQ::TEvProposePartitionConfig::TPtr& ev, const TActorContext&)
1001
1031
{
1002
- PendingEvents.emplace_back (ev->ReleaseBase ().Release ());
1032
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvProposePartitionConfig" );
1033
+
1034
+ AddPendingEvent (ev);
1003
1035
}
1004
1036
1005
1037
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext& /* ctx */ )
@@ -1009,7 +1041,7 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TAc
1009
1041
Y_ABORT_UNLESS (IsSupportive ());
1010
1042
1011
1043
ev->Get ()->OriginalPartition = ev->Sender ;
1012
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1044
+ AddPendingEvent (ev);
1013
1045
}
1014
1046
1015
1047
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TActorContext& /* ctx */ )
@@ -1018,7 +1050,7 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TA
1018
1050
1019
1051
Y_ABORT_UNLESS (!IsSupportive ());
1020
1052
1021
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1053
+ AddPendingEvent (ev);
1022
1054
}
1023
1055
1024
1056
void TPartition::HandleOnInit (TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActorContext& /* ctx */ )
@@ -1027,43 +1059,46 @@ void TPartition::HandleOnInit(TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActo
1027
1059
1028
1060
Y_ABORT_UNLESS (!IsSupportive ());
1029
1061
1030
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
1062
+ AddPendingEvent (ev);
1031
1063
}
1032
1064
1033
- void TPartition::Handle (TEvPQ::TEvTxCalcPredicate::TPtr& ev, const TActorContext& ctx)
1065
+ template <>
1066
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxCalcPredicate> ev, const TActorContext& ctx)
1034
1067
{
1035
- PQ_LOG_D (" Handle TEvPQ::TEvTxCalcPredicate" <<
1036
- " Step " << ev->Get ()->Step <<
1037
- " , TxId " << ev->Get ()->TxId );
1038
-
1039
1068
if (PlanStep.Defined () && TxId.Defined ()) {
1040
- if (GetStepAndTxId (*ev-> Get () ) < GetStepAndTxId (*PlanStep, *TxId)) {
1069
+ if (GetStepAndTxId (*ev) < GetStepAndTxId (*PlanStep, *TxId)) {
1041
1070
Send (Tablet,
1042
- MakeHolder<TEvPQ::TEvTxCalcPredicateResult>(ev->Get ()-> Step ,
1043
- ev->Get ()-> TxId ,
1071
+ MakeHolder<TEvPQ::TEvTxCalcPredicateResult>(ev->Step ,
1072
+ ev->TxId ,
1044
1073
Partition,
1045
1074
Nothing ()).Release ());
1046
1075
return ;
1047
1076
}
1048
1077
}
1049
1078
1050
- PushBackDistrTx (ev-> Release ());
1079
+ PushBackDistrTx (ev. release ());
1051
1080
1052
1081
ProcessTxsAndUserActs (ctx);
1053
1082
}
1054
1083
1055
- void TPartition::Handle (TEvPQ::TEvTxCommit ::TPtr& ev, const TActorContext& ctx)
1084
+ void TPartition::Handle (TEvPQ::TEvTxCalcPredicate ::TPtr& ev, const TActorContext& ctx)
1056
1085
{
1057
- PQ_LOG_D (" Handle TEvPQ::TEvTxCommit " <<
1086
+ PQ_LOG_D (" Handle TEvPQ::TEvTxCalcPredicate " <<
1058
1087
" Step " << ev->Get ()->Step <<
1059
1088
" , TxId " << ev->Get ()->TxId );
1060
1089
1090
+ ProcessPendingEvent (ev, ctx);
1091
+ }
1092
+
1093
+ template <>
1094
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxCommit> ev, const TActorContext& ctx)
1095
+ {
1061
1096
if (PlanStep.Defined () && TxId.Defined ()) {
1062
- if (GetStepAndTxId (*ev-> Get () ) < GetStepAndTxId (*PlanStep, *TxId)) {
1097
+ if (GetStepAndTxId (*ev) < GetStepAndTxId (*PlanStep, *TxId)) {
1063
1098
PQ_LOG_D (" Send TEvTxCommitDone" <<
1064
- " Step " << ev->Get ()-> Step <<
1065
- " , TxId " << ev->Get ()-> TxId );
1066
- ctx.Send (Tablet, MakeCommitDone (ev->Get ()-> Step , ev-> Get () ->TxId ).Release ());
1099
+ " Step " << ev->Step <<
1100
+ " , TxId " << ev->TxId );
1101
+ ctx.Send (Tablet, MakeCommitDone (ev->Step , ev->TxId ).Release ());
1067
1102
return ;
1068
1103
}
1069
1104
}
@@ -1073,33 +1108,42 @@ void TPartition::Handle(TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext& ctx)
1073
1108
Y_ABORT_UNLESS (TransactionsInflight.size () == 1 ,
1074
1109
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1075
1110
TabletID, Partition.OriginalPartitionId ,
1076
- ev->Get ()-> Step , ev-> Get () ->TxId );
1077
- PendingExplicitMessageGroups = ev->Get ()-> ExplicitMessageGroups ;
1111
+ ev->Step , ev->TxId );
1112
+ PendingExplicitMessageGroups = ev->ExplicitMessageGroups ;
1078
1113
} else {
1079
1114
Y_ABORT_UNLESS (!TransactionsInflight.empty (),
1080
1115
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1081
1116
TabletID, Partition.OriginalPartitionId ,
1082
- ev->Get ()-> Step , ev-> Get () ->TxId );
1083
- txIter = TransactionsInflight.find (ev->Get ()-> TxId );
1117
+ ev->Step , ev->TxId );
1118
+ txIter = TransactionsInflight.find (ev->TxId );
1084
1119
Y_ABORT_UNLESS (!txIter.IsEnd (),
1085
1120
" PQ: %" PRIu64 " , Partition: %" PRIu32 " , Step: %" PRIu64 " , TxId: %" PRIu64,
1086
1121
TabletID, Partition.OriginalPartitionId ,
1087
- ev->Get ()-> Step , ev-> Get () ->TxId );
1122
+ ev->Step , ev->TxId );
1088
1123
}
1089
1124
Y_ABORT_UNLESS (txIter->second ->State == ECommitState::Pending);
1090
1125
1091
1126
txIter->second ->State = ECommitState::Committed;
1092
1127
ProcessTxsAndUserActs (ctx);
1093
1128
}
1094
1129
1095
- void TPartition::Handle (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx)
1130
+ void TPartition::Handle (TEvPQ::TEvTxCommit::TPtr& ev, const TActorContext& ctx)
1131
+ {
1132
+ PQ_LOG_D (" Handle TEvPQ::TEvTxCommit" <<
1133
+ " Step " << ev->Get ()->Step <<
1134
+ " , TxId " << ev->Get ()->TxId );
1135
+
1136
+ ProcessPendingEvent (ev, ctx);
1137
+ }
1138
+
1139
+ template <>
1140
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvTxRollback> ev, const TActorContext& ctx)
1096
1141
{
1097
- auto * event = ev->Get ();
1098
1142
if (PlanStep.Defined () && TxId.Defined ()) {
1099
- if (GetStepAndTxId (*event ) < GetStepAndTxId (*PlanStep, *TxId)) {
1143
+ if (GetStepAndTxId (*ev ) < GetStepAndTxId (*PlanStep, *TxId)) {
1100
1144
PQ_LOG_D (" Rollback for" <<
1101
- " Step " << ev->Get ()-> Step <<
1102
- " , TxId " << ev->Get ()-> TxId );
1145
+ " Step " << ev->Step <<
1146
+ " , TxId " << ev->TxId );
1103
1147
return ;
1104
1148
}
1105
1149
}
@@ -1113,7 +1157,7 @@ void TPartition::Handle(TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx
1113
1157
Y_ABORT_UNLESS (!TransactionsInflight.empty (),
1114
1158
" PQ: %" PRIu64 " , Partition: %" PRIu32,
1115
1159
TabletID, Partition.OriginalPartitionId );
1116
- txIter = TransactionsInflight.find (ev->Get ()-> TxId );
1160
+ txIter = TransactionsInflight.find (ev->TxId );
1117
1161
Y_ABORT_UNLESS (!txIter.IsEnd (),
1118
1162
" PQ: %" PRIu64 " , Partition: %" PRIu32,
1119
1163
TabletID, Partition.OriginalPartitionId );
@@ -1124,13 +1168,17 @@ void TPartition::Handle(TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx
1124
1168
ProcessTxsAndUserActs (ctx);
1125
1169
}
1126
1170
1127
- void TPartition::Handle (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext& ctx) {
1128
- PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoRequest" );
1129
- TActorId originalPartition = ev->Get ()->OriginalPartition ;
1130
- if (!originalPartition) {
1131
- // original message
1132
- originalPartition = ev->Sender ;
1133
- }
1171
+ void TPartition::Handle (TEvPQ::TEvTxRollback::TPtr& ev, const TActorContext& ctx)
1172
+ {
1173
+ ProcessPendingEvent (ev, ctx);
1174
+ }
1175
+
1176
+ template <>
1177
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoRequest> ev, const TActorContext& ctx)
1178
+ {
1179
+ TActorId originalPartition = ev->OriginalPartition ;
1180
+ Y_ABORT_UNLESS (originalPartition != TActorId ());
1181
+
1134
1182
if (ClosedInternalPartition || WaitingForPreviousBlobQuota () || (CurrentStateFunc () != &TThis::StateIdle)) {
1135
1183
PQ_LOG_D (" Send TEvPQ::TEvGetWriteInfoError" );
1136
1184
auto * response = new TEvPQ::TEvGetWriteInfoError (Partition.InternalPartitionId ,
@@ -1162,6 +1210,14 @@ void TPartition::Handle(TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorCon
1162
1210
ctx.Send (originalPartition, response);
1163
1211
}
1164
1212
1213
+ void TPartition::Handle (TEvPQ::TEvGetWriteInfoRequest::TPtr& ev, const TActorContext& ctx) {
1214
+ PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoRequest" );
1215
+
1216
+ ev->Get ()->OriginalPartition = ev->Sender ;
1217
+
1218
+ ProcessPendingEvent (ev, ctx);
1219
+ }
1220
+
1165
1221
void TPartition::WriteInfoResponseHandler (
1166
1222
const TActorId& sender,
1167
1223
TGetWriteInfoResp&& ev,
@@ -1250,17 +1306,36 @@ TPartition::EProcessResult TPartition::ApplyWriteInfoResponse(TTransaction& tx)
1250
1306
return ret;
1251
1307
}
1252
1308
1309
+ template <>
1310
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoResponse> ev, const TActorContext& ctx)
1311
+ {
1312
+ const auto sender = ev->SupportivePartition ;
1313
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1314
+ }
1315
+
1253
1316
void TPartition::Handle (TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TActorContext& ctx) {
1254
1317
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoResponse" );
1255
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1318
+
1319
+ ev->Get ()->SupportivePartition = ev->Sender ;
1320
+
1321
+ ProcessPendingEvent (ev, ctx);
1256
1322
}
1257
1323
1324
+ template <>
1325
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoError> ev, const TActorContext& ctx)
1326
+ {
1327
+ const auto sender = ev->SupportivePartition ;
1328
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1329
+ }
1258
1330
1259
1331
void TPartition::Handle (TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActorContext& ctx) {
1260
1332
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoError " <<
1261
1333
" Cookie " << ev->Get ()->Cookie <<
1262
1334
" , Message " << ev->Get ()->Message );
1263
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1335
+
1336
+ ev->Get ()->SupportivePartition = ev->Sender ;
1337
+
1338
+ ProcessPendingEvent (ev, ctx);
1264
1339
}
1265
1340
1266
1341
void TPartition::ReplyToProposeOrPredicate (TSimpleSharedPtr<TTransaction>& tx, bool isPredicate) {
@@ -2698,16 +2773,6 @@ void TPartition::ChangePlanStepAndTxId(ui64 step, ui64 txId)
2698
2773
TxIdHasChanged = true ;
2699
2774
}
2700
2775
2701
- void TPartition::ResendPendingEvents (const TActorContext& ctx)
2702
- {
2703
- PQ_LOG_D (" Resend pending events. Count " << PendingEvents.size ());
2704
-
2705
- while (!PendingEvents.empty ()) {
2706
- ctx.Schedule (TDuration::Zero (), PendingEvents.front ().release ());
2707
- PendingEvents.pop_front ();
2708
- }
2709
- }
2710
-
2711
2776
TPartition::EProcessResult TPartition::PreProcessImmediateTx (const NKikimrPQ::TEvProposeTransaction& tx)
2712
2777
{
2713
2778
if (AffectedUsers.size () >= MAX_USERS) {
@@ -3560,14 +3625,17 @@ void TPartition::Handle(TEvPQ::TEvCheckPartitionStatusRequest::TPtr& ev, const T
3560
3625
3561
3626
void TPartition::HandleOnInit (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext&)
3562
3627
{
3628
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvDeletePartition" );
3629
+
3563
3630
Y_ABORT_UNLESS (IsSupportive ());
3564
3631
3565
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
3632
+ AddPendingEvent (ev);
3566
3633
}
3567
3634
3568
- void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& ctx)
3635
+ template <>
3636
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvDeletePartition> ev, const TActorContext& ctx)
3569
3637
{
3570
- PQ_LOG_D ( " Handle TEvPQ::TEvDeletePartition " );
3638
+ Y_UNUSED (ev );
3571
3639
3572
3640
Y_ABORT_UNLESS (IsSupportive ());
3573
3641
Y_ABORT_UNLESS (DeletePartitionState == DELETION_NOT_INITED);
@@ -3577,6 +3645,13 @@ void TPartition::Handle(TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& c
3577
3645
ProcessTxsAndUserActs (ctx);
3578
3646
}
3579
3647
3648
+ void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext& ctx)
3649
+ {
3650
+ PQ_LOG_D (" Handle TEvPQ::TEvDeletePartition" );
3651
+
3652
+ ProcessPendingEvent (ev, ctx);
3653
+ }
3654
+
3580
3655
void TPartition::ScheduleNegativeReplies ()
3581
3656
{
3582
3657
auto processQueue = [&](std::deque<TUserActionAndTransactionEvent>& queue) {
@@ -3647,6 +3722,23 @@ void TPartition::ScheduleTransactionCompleted(const NKikimrPQ::TEvProposeTransac
3647
3722
MakeHolder<TEvPQ::TEvTransactionCompleted>(writeId).Release ());
3648
3723
}
3649
3724
3725
+ void TPartition::ProcessPendingEvents (const TActorContext& ctx)
3726
+ {
3727
+ PQ_LOG_D (" Process pending events. Count " << PendingEvents.size ());
3728
+
3729
+ while (!PendingEvents.empty ()) {
3730
+ auto ev = std::move (PendingEvents.front ());
3731
+ PendingEvents.pop_front ();
3732
+
3733
+ auto visitor = [this , &ctx](auto && v) {
3734
+ using T = std::decay_t <decltype (v)>;
3735
+ ProcessPendingEvent (std::forward<T>(v), ctx);
3736
+ };
3737
+
3738
+ std::visit (visitor, std::move (ev));
3739
+ }
3740
+ }
3741
+
3650
3742
const NKikimrPQ::TPQTabletConfig::TPartition* TPartition::GetPartitionConfig (const NKikimrPQ::TPQTabletConfig& config)
3651
3743
{
3652
3744
return NPQ::GetPartitionConfig (config, Partition.OriginalPartitionId );
0 commit comments