@@ -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,
@@ -1246,17 +1302,36 @@ TPartition::EProcessResult TPartition::ApplyWriteInfoResponse(TTransaction& tx)
1246
1302
return ret;
1247
1303
}
1248
1304
1305
+ template <>
1306
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoResponse> ev, const TActorContext& ctx)
1307
+ {
1308
+ const auto sender = ev->SupportivePartition ;
1309
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1310
+ }
1311
+
1249
1312
void TPartition::Handle (TEvPQ::TEvGetWriteInfoResponse::TPtr& ev, const TActorContext& ctx) {
1250
1313
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoResponse" );
1251
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1314
+
1315
+ ev->Get ()->SupportivePartition = ev->Sender ;
1316
+
1317
+ ProcessPendingEvent (ev, ctx);
1252
1318
}
1253
1319
1320
+ template <>
1321
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvGetWriteInfoError> ev, const TActorContext& ctx)
1322
+ {
1323
+ const auto sender = ev->SupportivePartition ;
1324
+ WriteInfoResponseHandler (sender, ev.release (), ctx);
1325
+ }
1254
1326
1255
1327
void TPartition::Handle (TEvPQ::TEvGetWriteInfoError::TPtr& ev, const TActorContext& ctx) {
1256
1328
PQ_LOG_D (" Handle TEvPQ::TEvGetWriteInfoError " <<
1257
1329
" Cookie " << ev->Get ()->Cookie <<
1258
1330
" , Message " << ev->Get ()->Message );
1259
- WriteInfoResponseHandler (ev->Sender , ev->Release (), ctx);
1331
+
1332
+ ev->Get ()->SupportivePartition = ev->Sender ;
1333
+
1334
+ ProcessPendingEvent (ev, ctx);
1260
1335
}
1261
1336
1262
1337
void TPartition::ReplyToProposeOrPredicate (TSimpleSharedPtr<TTransaction>& tx, bool isPredicate) {
@@ -2692,16 +2767,6 @@ void TPartition::ChangePlanStepAndTxId(ui64 step, ui64 txId)
2692
2767
TxIdHasChanged = true ;
2693
2768
}
2694
2769
2695
- void TPartition::ResendPendingEvents (const TActorContext& ctx)
2696
- {
2697
- PQ_LOG_D (" Resend pending events. Count " << PendingEvents.size ());
2698
-
2699
- while (!PendingEvents.empty ()) {
2700
- ctx.Schedule (TDuration::Zero (), PendingEvents.front ().release ());
2701
- PendingEvents.pop_front ();
2702
- }
2703
- }
2704
-
2705
2770
TPartition::EProcessResult TPartition::PreProcessImmediateTx (const NKikimrPQ::TEvProposeTransaction& tx)
2706
2771
{
2707
2772
if (AffectedUsers.size () >= MAX_USERS) {
@@ -3554,14 +3619,17 @@ void TPartition::Handle(TEvPQ::TEvCheckPartitionStatusRequest::TPtr& ev, const T
3554
3619
3555
3620
void TPartition::HandleOnInit (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext&)
3556
3621
{
3622
+ PQ_LOG_D (" HandleOnInit TEvPQ::TEvDeletePartition" );
3623
+
3557
3624
Y_ABORT_UNLESS (IsSupportive ());
3558
3625
3559
- PendingEvents. emplace_back (ev-> ReleaseBase (). Release () );
3626
+ AddPendingEvent (ev);
3560
3627
}
3561
3628
3562
- void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& ctx)
3629
+ template <>
3630
+ void TPartition::ProcessPendingEvent (std::unique_ptr<TEvPQ::TEvDeletePartition> ev, const TActorContext& ctx)
3563
3631
{
3564
- PQ_LOG_D ( " Handle TEvPQ::TEvDeletePartition " );
3632
+ Y_UNUSED (ev );
3565
3633
3566
3634
Y_ABORT_UNLESS (IsSupportive ());
3567
3635
Y_ABORT_UNLESS (DeletePartitionState == DELETION_NOT_INITED);
@@ -3571,6 +3639,13 @@ void TPartition::Handle(TEvPQ::TEvDeletePartition::TPtr&, const TActorContext& c
3571
3639
ProcessTxsAndUserActs (ctx);
3572
3640
}
3573
3641
3642
+ void TPartition::Handle (TEvPQ::TEvDeletePartition::TPtr& ev, const TActorContext& ctx)
3643
+ {
3644
+ PQ_LOG_D (" Handle TEvPQ::TEvDeletePartition" );
3645
+
3646
+ ProcessPendingEvent (ev, ctx);
3647
+ }
3648
+
3574
3649
void TPartition::ScheduleNegativeReplies ()
3575
3650
{
3576
3651
auto processQueue = [&](std::deque<TUserActionAndTransactionEvent>& queue) {
@@ -3641,6 +3716,23 @@ void TPartition::ScheduleTransactionCompleted(const NKikimrPQ::TEvProposeTransac
3641
3716
MakeHolder<TEvPQ::TEvTransactionCompleted>(writeId).Release ());
3642
3717
}
3643
3718
3719
+ void TPartition::ProcessPendingEvents (const TActorContext& ctx)
3720
+ {
3721
+ PQ_LOG_D (" Process pending events. Count " << PendingEvents.size ());
3722
+
3723
+ while (!PendingEvents.empty ()) {
3724
+ auto ev = std::move (PendingEvents.front ());
3725
+ PendingEvents.pop_front ();
3726
+
3727
+ auto visitor = [this , &ctx](auto && v) {
3728
+ using T = std::decay_t <decltype (v)>;
3729
+ ProcessPendingEvent (std::forward<T>(v), ctx);
3730
+ };
3731
+
3732
+ std::visit (visitor, std::move (ev));
3733
+ }
3734
+ }
3735
+
3644
3736
const NKikimrPQ::TPQTabletConfig::TPartition* TPartition::GetPartitionConfig (const NKikimrPQ::TPQTabletConfig& config)
3645
3737
{
3646
3738
return NPQ::GetPartitionConfig (config, Partition.OriginalPartitionId );
0 commit comments