@@ -48,14 +48,26 @@ class TGateway : public IYtGateway {
48
48
{}
49
49
50
50
void OpenSession (TOpenSessionOptions&& options) final {
51
+ with_lock (SessionGenerationsLock_) {
52
+ SessionGenerations_[options.SessionId ()] = 0 ;
53
+ }
54
+
51
55
return Inner_->OpenSession (std::move (options));
52
56
}
53
57
54
58
NThreading::TFuture<void > CloseSession (TCloseSessionOptions&& options) final {
59
+ with_lock (SessionGenerationsLock_) {
60
+ SessionGenerations_.erase (options.SessionId ());
61
+ }
62
+
55
63
return Inner_->CloseSession (std::move (options));
56
64
}
57
65
58
66
NThreading::TFuture<void > CleanupSession (TCleanupSessionOptions&& options) final {
67
+ with_lock (SessionGenerationsLock_) {
68
+ ++SessionGenerations_[options.SessionId ()];
69
+ }
70
+
59
71
return Inner_->CleanupSession (std::move (options));
60
72
}
61
73
@@ -166,8 +178,9 @@ class TGateway : public IYtGateway {
166
178
});
167
179
}
168
180
169
- static TString MakeGetTableInfoKey (const TTableReq& req, ui32 epoch) {
181
+ static TString MakeGetTableInfoKey (const TTableReq& req, ui32 epoch, ui64 generation ) {
170
182
auto tableNode = NYT::TNode ()
183
+ (" Generation" , generation)
171
184
(" Cluster" , req.Cluster ())
172
185
(" Table" , req.Table ());
173
186
@@ -199,12 +212,17 @@ class TGateway : public IYtGateway {
199
212
}
200
213
201
214
NThreading::TFuture<TTableInfoResult> GetTableInfo (TGetTableInfoOptions&& options) final {
215
+ ui64 generation;
216
+ with_lock (SessionGenerationsLock_) {
217
+ generation = SessionGenerations_[options.SessionId ()];
218
+ }
219
+
202
220
if (QContext_.CanRead ()) {
203
221
TTableInfoResult res;
204
222
res.SetSuccess ();
205
223
for (const auto & req : options.Tables ()) {
206
224
TTableInfoResult::TTableData data;
207
- auto key = MakeGetTableInfoKey (req, options.Epoch ());
225
+ auto key = MakeGetTableInfoKey (req, options.Epoch (), generation );
208
226
auto item = QContext_.GetReader ()->Get ({YtGateway_GetTableInfo, key}).GetValueSync ();
209
227
if (!item) {
210
228
throw yexception () << " Missing replay data" ;
@@ -246,7 +264,7 @@ class TGateway : public IYtGateway {
246
264
247
265
auto optionsDup = options;
248
266
return Inner_->GetTableInfo (std::move (options))
249
- .Subscribe ([optionsDup, qContext = QContext_](const NThreading::TFuture<TTableInfoResult>& future) {
267
+ .Subscribe ([optionsDup, qContext = QContext_, generation ](const NThreading::TFuture<TTableInfoResult>& future) {
250
268
if (!qContext.CanWrite () || future.HasException ()) {
251
269
return ;
252
270
}
@@ -260,7 +278,7 @@ class TGateway : public IYtGateway {
260
278
for (size_t i = 0 ; i < res.Data .size (); ++i) {
261
279
const auto & req = optionsDup.Tables ()[i];
262
280
const auto & data = res.Data [i];
263
- auto key = MakeGetTableInfoKey (req, optionsDup.Epoch ());
281
+ auto key = MakeGetTableInfoKey (req, optionsDup.Epoch (), generation );
264
282
265
283
auto attrsNode = NYT::TNode::CreateMap ();
266
284
if (data.Meta ) {
@@ -303,8 +321,9 @@ class TGateway : public IYtGateway {
303
321
});
304
322
}
305
323
306
- static TString MakeGetTableRangeKey (const TTableRangeOptions& options) {
324
+ static TString MakeGetTableRangeKey (const TTableRangeOptions& options, ui64 generation ) {
307
325
auto keyNode = NYT::TNode ()
326
+ (" Generation" , generation)
308
327
(" Cluster" , options.Cluster ())
309
328
(" Prefix" , options.Prefix ())
310
329
(" Suffix" , options.Suffix ());
@@ -317,9 +336,14 @@ class TGateway : public IYtGateway {
317
336
}
318
337
319
338
NThreading::TFuture<TTableRangeResult> GetTableRange (TTableRangeOptions&& options) final {
339
+ ui64 generation;
340
+ with_lock (SessionGenerationsLock_) {
341
+ generation = SessionGenerations_[options.SessionId ()];
342
+ }
343
+
320
344
TString key;
321
345
if (QContext_) {
322
- key = MakeGetTableRangeKey (options);
346
+ key = MakeGetTableRangeKey (options, generation );
323
347
}
324
348
325
349
if (QContext_.CanRead ()) {
@@ -407,21 +431,22 @@ class TGateway : public IYtGateway {
407
431
});
408
432
}
409
433
410
- static TString MakeGetFolderKey (const TFolderOptions& options) {
434
+ static TString MakeGetFolderKey (const TFolderOptions& options, ui64 generation ) {
411
435
auto attrNode = NYT::TNode::CreateList ();
412
436
for (const auto & attr : options.Attributes ()) {
413
437
attrNode.Add (NYT::TNode (attr));
414
438
}
415
439
416
440
auto keyNode = NYT::TNode ()
441
+ (" Generation" , generation)
417
442
(" Cluster" , options.Cluster ())
418
443
(" Prefix" , options.Prefix ())
419
444
(" Attributes" , attrNode);
420
445
421
446
return MakeHash (NYT::NodeToCanonicalYsonString (keyNode, NYT::NYson::EYsonFormat::Binary));
422
447
}
423
448
424
- static TString MakeResolveLinksKey (const TResolveOptions& options) {
449
+ static TString MakeResolveLinksKey (const TResolveOptions& options, ui64 generation ) {
425
450
auto itemsNode = NYT::TNode::CreateList ();
426
451
for (const auto & item : options.Items ()) {
427
452
auto attrNode = NYT::TNode::CreateList ();
@@ -438,13 +463,14 @@ class TGateway : public IYtGateway {
438
463
}
439
464
440
465
auto keyNode = NYT::TNode ()
466
+ (" Generation" , generation)
441
467
(" Cluster" , options.Cluster ())
442
468
(" Items" , itemsNode);
443
469
444
470
return MakeHash (NYT::NodeToCanonicalYsonString (keyNode, NYT::NYson::EYsonFormat::Binary));
445
471
}
446
472
447
- static TString MakeGetFoldersKey (const TBatchFolderOptions& options) {
473
+ static TString MakeGetFoldersKey (const TBatchFolderOptions& options, ui64 generation ) {
448
474
auto itemsNode = NYT::TNode ();
449
475
TMap<TString, size_t > order;
450
476
for (size_t i = 0 ; i < options.Folders ().size (); ++i) {
@@ -464,6 +490,7 @@ class TGateway : public IYtGateway {
464
490
}
465
491
466
492
auto keyNode = NYT::TNode ()
493
+ (" Generation" , generation)
467
494
(" Cluster" , options.Cluster ())
468
495
(" Items" , itemsNode);
469
496
@@ -490,8 +517,13 @@ class TGateway : public IYtGateway {
490
517
}
491
518
492
519
NThreading::TFuture<TFolderResult> GetFolder (TFolderOptions&& options) final {
520
+ ui64 generation;
521
+ with_lock (SessionGenerationsLock_) {
522
+ generation = SessionGenerations_[options.SessionId ()];
523
+ }
524
+
493
525
if (QContext_.CanRead ()) {
494
- const auto & key = MakeGetFolderKey (options);
526
+ const auto & key = MakeGetFolderKey (options, generation );
495
527
auto item = QContext_.GetReader ()->Get ({YtGateway_GetFolder, key}).GetValueSync ();
496
528
if (!item) {
497
529
throw yexception () << " Missing replay data" ;
@@ -520,7 +552,7 @@ class TGateway : public IYtGateway {
520
552
521
553
auto optionsDup = options;
522
554
return Inner_->GetFolder (std::move (options))
523
- .Subscribe ([optionsDup, qContext = QContext_](const NThreading::TFuture<TFolderResult>& future) {
555
+ .Subscribe ([optionsDup, qContext = QContext_, generation ](const NThreading::TFuture<TFolderResult>& future) {
524
556
if (!qContext.CanWrite () || future.HasException ()) {
525
557
return ;
526
558
}
@@ -530,7 +562,7 @@ class TGateway : public IYtGateway {
530
562
return ;
531
563
}
532
564
533
- const auto & key = MakeGetFolderKey (optionsDup);
565
+ const auto & key = MakeGetFolderKey (optionsDup, generation );
534
566
auto valueNode = NYT::TNode ();
535
567
536
568
if (std::holds_alternative<TFileLinkPtr>(res.ItemsOrFileLink )) {
@@ -550,10 +582,15 @@ class TGateway : public IYtGateway {
550
582
}
551
583
552
584
NThreading::TFuture<TBatchFolderResult> ResolveLinks (TResolveOptions&& options) final {
585
+ ui64 generation;
586
+ with_lock (SessionGenerationsLock_) {
587
+ generation = SessionGenerations_[options.SessionId ()];
588
+ }
589
+
553
590
if (QContext_.CanRead ()) {
554
591
TBatchFolderResult res;
555
592
res.SetSuccess ();
556
- const auto & key = MakeResolveLinksKey (options);
593
+ const auto & key = MakeResolveLinksKey (options, generation );
557
594
auto item = QContext_.GetReader ()->Get ({YtGateway_ResolveLinks, key}).GetValueSync ();
558
595
if (!item) {
559
596
throw yexception () << " Missing replay data" ;
@@ -571,7 +608,7 @@ class TGateway : public IYtGateway {
571
608
572
609
auto optionsDup = options;
573
610
return Inner_->ResolveLinks (std::move (options))
574
- .Subscribe ([optionsDup, qContext = QContext_](const NThreading::TFuture<TBatchFolderResult>& future) {
611
+ .Subscribe ([optionsDup, qContext = QContext_, generation ](const NThreading::TFuture<TBatchFolderResult>& future) {
575
612
if (!qContext.CanWrite () || future.HasException ()) {
576
613
return ;
577
614
}
@@ -581,7 +618,7 @@ class TGateway : public IYtGateway {
581
618
return ;
582
619
}
583
620
584
- const auto & key = MakeResolveLinksKey (optionsDup);
621
+ const auto & key = MakeResolveLinksKey (optionsDup, generation );
585
622
NYT::TNode valueNode = NYT::TNode::CreateList ();
586
623
for (const auto & item : res.Items ) {
587
624
valueNode.Add (SerializeFolderItem (item));
@@ -593,10 +630,15 @@ class TGateway : public IYtGateway {
593
630
}
594
631
595
632
NThreading::TFuture<TBatchFolderResult> GetFolders (TBatchFolderOptions&& options) final {
633
+ ui64 generation;
634
+ with_lock (SessionGenerationsLock_) {
635
+ generation = SessionGenerations_[options.SessionId ()];
636
+ }
637
+
596
638
if (QContext_.CanRead ()) {
597
639
TBatchFolderResult res;
598
640
res.SetSuccess ();
599
- const auto & key = MakeGetFoldersKey (options);
641
+ const auto & key = MakeGetFoldersKey (options, generation );
600
642
auto item = QContext_.GetReader ()->Get ({YtGateway_GetFolders, key}).GetValueSync ();
601
643
if (!item) {
602
644
throw yexception () << " Missing replay data" ;
@@ -614,7 +656,7 @@ class TGateway : public IYtGateway {
614
656
615
657
auto optionsDup = options;
616
658
return Inner_->GetFolders (std::move (options))
617
- .Subscribe ([optionsDup, qContext = QContext_](const NThreading::TFuture<TBatchFolderResult>& future) {
659
+ .Subscribe ([optionsDup, qContext = QContext_, generation ](const NThreading::TFuture<TBatchFolderResult>& future) {
618
660
if (!qContext.CanWrite () || future.HasException ()) {
619
661
return ;
620
662
}
@@ -624,7 +666,7 @@ class TGateway : public IYtGateway {
624
666
return ;
625
667
}
626
668
627
- const auto & key = MakeGetFoldersKey (optionsDup);
669
+ const auto & key = MakeGetFoldersKey (optionsDup, generation );
628
670
NYT::TNode valueNode = NYT::TNode::CreateList ();
629
671
for (const auto & item : res.Items ) {
630
672
valueNode.Add (SerializeFolderItem (item));
@@ -699,8 +741,9 @@ class TGateway : public IYtGateway {
699
741
return Inner_->DropTrackables (std::move (options));
700
742
}
701
743
702
- static TString MakePathStatKey (const TString& cluster, bool extended, const TPathStatReq& req) {
744
+ static TString MakePathStatKey (const TString& cluster, bool extended, const TPathStatReq& req, ui64 generation ) {
703
745
auto node = NYT::TNode ()
746
+ (" Generation" , generation)
704
747
(" Cluster" , cluster)
705
748
(" Extended" , extended);
706
749
@@ -766,13 +809,18 @@ class TGateway : public IYtGateway {
766
809
}
767
810
768
811
NThreading::TFuture<TPathStatResult> PathStat (TPathStatOptions&& options) final {
812
+ ui64 generation;
813
+ with_lock (SessionGenerationsLock_) {
814
+ generation = SessionGenerations_[options.SessionId ()];
815
+ }
816
+
769
817
if (QContext_.CanRead ()) {
770
818
TPathStatResult res;
771
819
res.DataSize .resize (options.Paths ().size (), 0 );
772
820
res.Extended .resize (options.Paths ().size ());
773
821
774
822
for (ui32 index = 0 ; index < options.Paths ().size (); ++index ) {
775
- const auto & key = MakePathStatKey (options.Cluster (), options.Extended (), options.Paths ()[index ]);
823
+ const auto & key = MakePathStatKey (options.Cluster (), options.Extended (), options.Paths ()[index ], generation );
776
824
auto item = QContext_.GetReader ()->Get ({YtGateway_PathStat, key}).GetValueSync ();
777
825
if (!item) {
778
826
throw yexception () << " Missing replay data" ;
@@ -789,7 +837,7 @@ class TGateway : public IYtGateway {
789
837
790
838
auto optionsDup = options;
791
839
return Inner_->PathStat (std::move (options))
792
- .Subscribe ([optionsDup, qContext = QContext_](const NThreading::TFuture<TPathStatResult>& future) {
840
+ .Subscribe ([optionsDup, qContext = QContext_, generation ](const NThreading::TFuture<TPathStatResult>& future) {
793
841
if (!qContext.CanWrite () || future.HasException ()) {
794
842
return ;
795
843
}
@@ -800,21 +848,26 @@ class TGateway : public IYtGateway {
800
848
}
801
849
802
850
for (ui32 index = 0 ; index < optionsDup.Paths ().size (); ++index ) {
803
- const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ]);
851
+ const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ], generation );
804
852
auto value = SerializePathStat (res, index );
805
853
qContext.GetWriter ()->Put ({YtGateway_PathStat, key}, value).GetValueSync ();
806
854
}
807
855
});
808
856
}
809
857
810
858
TPathStatResult TryPathStat (TPathStatOptions&& options) final {
859
+ ui64 generation;
860
+ with_lock (SessionGenerationsLock_) {
861
+ generation = SessionGenerations_[options.SessionId ()];
862
+ }
863
+
811
864
if (QContext_.CanRead ()) {
812
865
TPathStatResult res;
813
866
res.DataSize .resize (options.Paths ().size (), 0 );
814
867
res.Extended .resize (options.Paths ().size ());
815
868
816
869
for (ui32 index = 0 ; index < options.Paths ().size (); ++index ) {
817
- const auto & key = MakePathStatKey (options.Cluster (), options.Extended (), options.Paths ()[index ]);
870
+ const auto & key = MakePathStatKey (options.Cluster (), options.Extended (), options.Paths ()[index ], generation );
818
871
bool allow = false ;
819
872
if (PathStatKeys_.contains (key)) {
820
873
allow = true ;
@@ -851,15 +904,15 @@ class TGateway : public IYtGateway {
851
904
852
905
if (!res.Success ()) {
853
906
for (ui32 index = 0 ; index < optionsDup.Paths ().size (); ++index ) {
854
- const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ]);
907
+ const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ], generation );
855
908
QContext_.GetWriter ()->Put ({YtGateway_PathStatMissing, key}, " 1" ).GetValueSync ();
856
909
}
857
910
858
911
return res;
859
912
}
860
913
861
914
for (ui32 index = 0 ; index < optionsDup.Paths ().size (); ++index ) {
862
- const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ]);
915
+ const auto & key = MakePathStatKey (optionsDup.Cluster (), optionsDup.Extended (), optionsDup.Paths ()[index ], generation );
863
916
auto value = SerializePathStat (res, index );
864
917
QContext_.GetWriter ()->Put ({YtGateway_PathStat, key}, value).GetValueSync ();
865
918
}
@@ -937,6 +990,8 @@ class TGateway : public IYtGateway {
937
990
const TIntrusivePtr<IRandomProvider> RandomProvider_;
938
991
const TFileStoragePtr FileStorage_;
939
992
THashSet<TString> PathStatKeys_;
993
+ THashMap<TString, ui64> SessionGenerations_;
994
+ TMutex SessionGenerationsLock_;
940
995
};
941
996
942
997
}
0 commit comments