Browse Source

Add TBlockAndGetActor.

yuryalekseev 2 years ago
parent
commit
3c990a8ee0

+ 0 - 23
contrib/libs/libxml/COPYING

@@ -1,23 +0,0 @@
-Except where otherwise noted in the source code (e.g. the files hash.c,
-list.c and the trio files, which are covered by a similar licence but
-with different Copyright notices) all the files are:
-
- Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is fur-
-nished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

+ 3 - 1
ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp

@@ -907,6 +907,7 @@ public:
             << " MinGeneration# " << MinGeneration
             << " ReadBody# " << (ReadBody ? "true" : "false")
             << " Deadline# " << Deadline
+            << " ForceBlockedGeneration# " << ForceBlockedGeneration
             << " FromLeader# " << (FromLeader ? "true" : "false")
             << " RestartCounter# " << RestartCounter);
 
@@ -937,7 +938,8 @@ public:
                 << " vDiskId# " << vd
                 << " node# " << Info->GetActorId(vd).NodeId()
                 << " msg# " << msg->ToString()
-                << " cookie# " << cookie);
+                << " cookie# " << cookie
+                << " ForceBlockedGeneration# " << msg->Record.GetForceBlockedGeneration());
             CountEvent(*msg);
             SendToQueue(std::move(msg), cookie);
             TotalSent++;

+ 0 - 1
ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp

@@ -80,7 +80,6 @@ public:
                 nullptr,                                // cookie
                 ForceBlockedGeneration);                // forceBlockedGeneration
 
-
             // disable barrier checking
             query->Record.SetSuppressBarrierCheck(true);
 

+ 1 - 0
ydb/core/blobstorage/vdisk/common/vdisk_events.h

@@ -1185,6 +1185,7 @@ namespace NKikimr {
                 << " Internals# " << record.GetShowInternals()
                 << " TabletId# " << record.GetTabletId()
                 << " AcquireBlockedGeneration# " << record.GetAcquireBlockedGeneration()
+                << " ForceBlockedGeneration# " << record.GetForceBlockedGeneration()
                 << "}";
             return str.Str();
         }

+ 1 - 0
ydb/core/blobstorage/vdisk/skeleton/CMakeLists.txt

@@ -25,6 +25,7 @@ target_sources(blobstorage-vdisk-skeleton PRIVATE
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp
+  ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/skeleton_block_and_get.cpp
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp
   ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/vdisk/skeleton/skeleton_mon_dbmainpage.cpp

+ 20 - 0
ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp

@@ -15,6 +15,7 @@
 #include "skeleton_events.h"
 #include "skeleton_capturevdisklayout.h"
 #include "skeleton_compactionstate.h"
+#include "skeleton_block_and_get.h"
 #include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
 #include <ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h>
 #include <ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h>
@@ -889,6 +890,25 @@ namespace NKikimr {
                     && Hull->IsBlocked(record.GetReaderTabletData().GetId(), {record.GetReaderTabletData().GetGeneration(), 0}).Status != TBlocksCache::EStatus::OK) {
                 ReplyError(NKikimrProto::BLOCKED, "tablet's generation is blocked", ev, ctx, now);
             } else {
+                if (ev->Get()->Record.GetForceBlockedGeneration() > 0) {
+                    auto tabletGeneration = ev->Get()->Record.GetForceBlockedGeneration();
+                    ui32 blockedGeneration = 0;
+                    if (!Hull->GetBlocked(record.GetTabletId(), &blockedGeneration) || blockedGeneration < tabletGeneration) {
+                         // TODO: add counter
+                        auto actor = CreateBlockAndGetActor(
+                            std::move(ev),
+                            SelfId(),
+                            VCtx,
+                            SkeletonFrontIDPtr,
+                            SelfVDiskId,
+                            Db->GetVDiskIncarnationGuid(),
+                            GInfo
+                        );
+                        ctx.Register(actor.release());
+                        return;
+                    }
+                }
+
                 std::optional<THullDsSnap> fullSnap;
                 if (record.HasSnapshotId()) {
                     const auto it = Snapshots.find(record.GetSnapshotId());

+ 114 - 0
ydb/core/blobstorage/vdisk/skeleton/skeleton_block_and_get.cpp

@@ -0,0 +1,114 @@
+#include "skeleton_block_and_get.h"
+#include "blobstorage_skeletonerr.h"
+
+#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
+#include <ydb/core/blobstorage/vdisk/common/vdisk_response.h>
+
+#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+
+#include <memory>
+
+namespace NKikimr {
+
+class TBlockAndGetActor : public TActorBootstrapped<TBlockAndGetActor> {
+public:
+    TBlockAndGetActor() = delete;
+    explicit TBlockAndGetActor(
+        TEvBlobStorage::TEvVGet::TPtr ev,
+        NActors::TActorId skeletonId,
+        TIntrusivePtr<TVDiskContext> vCtx,
+        TActorIDPtr skeletonFrontIDPtr,
+        TVDiskID selfVDiskId,
+        TVDiskIncarnationGuid vDiskIncarnationGuid,
+        TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> gInfo)
+        : SenderId(ev->Sender)
+        , SkeletonId(skeletonId)
+        , VCtx(vCtx)
+        , SkeletonFrontIDPtr(skeletonFrontIDPtr)
+        , SelfVDiskId(selfVDiskId)
+        , VDiskIncarnationGuid(vDiskIncarnationGuid)
+        , GInfo(gInfo)
+    {
+        Y_VERIFY(ev->Get()->Record.GetForceBlockedGeneration() > 0);
+        Request = std::move(ev);
+    }
+
+    void Bootstrap() {
+        // create TEvVBlock request
+        auto request = std::make_unique<TEvBlobStorage::TEvVBlock>(
+            Request->Get()->Record.GetTabletId(),
+            Request->Get()->Record.GetForceBlockedGeneration(),
+            VDiskIDFromVDiskID(Request->Get()->Record.GetVDiskID()),
+            Request->Get()->Record.GetMsgQoS().HasDeadlineSeconds() ? 
+                TInstant::Seconds(Request->Get()->Record.GetMsgQoS().GetDeadlineSeconds()) :
+                TInstant::Max()
+        );
+
+        // send TEvVBlock request
+        Send(SkeletonId, request.release());
+
+        Become(&TThis::StateWait);
+    }
+
+    STRICT_STFUNC(StateWait,
+        hFunc(TEvBlobStorage::TEvVBlockResult, Handle);
+        cFunc(TEvents::TSystem::Poison, PassAway);
+    )
+
+    void Handle(TEvBlobStorage::TEvVBlockResult::TPtr &ev) {
+        switch (ev->Get()->Record.GetStatus()) {
+        case NKikimrProto::OK:
+            [[fallthrough]];
+        case NKikimrProto::ALREADY:
+            break;
+        default: {
+                // we failed to block required generation, so return failure
+                auto response = NErrBuilder::ErroneousResult(
+                    VCtx,
+                    // return BLOCKED so that dsproxy returns right away and doesn't try remaining vdisks
+                    NKikimrProto::BLOCKED,
+                    "failed to block required generation",
+                    Request,
+                    TAppData::TimeProvider->Now(),
+                    SkeletonFrontIDPtr,
+                    SelfVDiskId,
+                    VDiskIncarnationGuid,
+                    GInfo
+                );
+                SendVDiskResponse(TActivationContext::AsActorContext(), SenderId, response.release(), Request->Cookie);
+                return PassAway();
+            }
+        }
+
+        // send TEvVGet request, the reply will go directly to sender.
+        // there is no need to clear ForceBlockedGeneration parameter
+        // since by now the required generation has been blocked.
+        TActivationContext::Send(Request.Release());
+        PassAway();
+    }
+
+private:
+    NActors::TActorId SenderId;
+    NActors::TActorId SkeletonId;
+    TIntrusivePtr<TVDiskContext> VCtx;
+    TActorIDPtr SkeletonFrontIDPtr;
+    TVDiskID SelfVDiskId;
+    TVDiskIncarnationGuid VDiskIncarnationGuid;
+    TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> GInfo;
+    TEvBlobStorage::TEvVGet::TPtr Request;
+};
+
+std::unique_ptr<NActors::IActor> CreateBlockAndGetActor(
+    TEvBlobStorage::TEvVGet::TPtr ev,
+    NActors::TActorId skeletonId,
+    TIntrusivePtr<TVDiskContext> vCtx,
+    TActorIDPtr skeletonFrontIDPtr,
+    TVDiskID selfVDiskId,
+    TVDiskIncarnationGuid vDiskIncarnationGuid,
+    TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> gInfo)
+{
+    return std::make_unique<TBlockAndGetActor>(ev, skeletonId, vCtx, skeletonFrontIDPtr, selfVDiskId, vDiskIncarnationGuid, gInfo);
+}
+
+} // NKikimr

+ 20 - 0
ydb/core/blobstorage/vdisk/skeleton/skeleton_block_and_get.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
+
+#include <library/cpp/actors/core/actor.h>
+
+#include <memory>
+
+namespace NKikimr {
+
+std::unique_ptr<NActors::IActor> CreateBlockAndGetActor(
+    TEvBlobStorage::TEvVGet::TPtr ev,
+    NActors::TActorId skeletonId,
+    TIntrusivePtr<TVDiskContext> vCtx,
+    TActorIDPtr skeletonFrontIDPtr,
+    TVDiskID selfVDiskId,
+    TVDiskIncarnationGuid vDiskIncarnationGuid,
+    TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> gInfo);
+
+} // NKikimr