Browse Source

YT-21434: Make sure system invokers are active before shutdown
1d45d044e90ad310e6e002f8446320e56dcdf6fb

arkady-e1ppa 10 months ago
parent
commit
bb793583d8

+ 8 - 0
yt/yt/core/concurrency/fiber_scheduler_thread.cpp

@@ -897,6 +897,10 @@ private:
 
 
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
 
+std::atomic<bool> ShutdownManagerPrepared_ = false;
+
+////////////////////////////////////////////////////////////////////////////////
+
 TFiberSchedulerThread::TFiberSchedulerThread(
 TFiberSchedulerThread::TFiberSchedulerThread(
     TString threadGroupName,
     TString threadGroupName,
     TString threadName,
     TString threadName,
@@ -911,6 +915,10 @@ void TFiberSchedulerThread::ThreadMain()
     // Hold this strongly.
     // Hold this strongly.
     auto this_ = MakeStrong(this);
     auto this_ = MakeStrong(this);
 
 
+    if (!ShutdownManagerPrepared_.exchange(true, std::memory_order::relaxed)) {
+        EnsureSafeShutdown();
+    }
+
     try {
     try {
         YT_LOG_DEBUG("Thread started (Name: %v)",
         YT_LOG_DEBUG("Thread started (Name: %v)",
             GetThreadName());
             GetThreadName());

+ 13 - 0
yt/yt/core/misc/shutdown.cpp

@@ -1,5 +1,7 @@
 #include "shutdown.h"
 #include "shutdown.h"
 
 
+#include <yt/yt/core/concurrency/system_invokers.h>
+
 #include <yt/yt/core/misc/collection_helpers.h>
 #include <yt/yt/core/misc/collection_helpers.h>
 #include <yt/yt/core/misc/proc.h>
 #include <yt/yt/core/misc/proc.h>
 #include <yt/yt/core/misc/singleton.h>
 #include <yt/yt/core/misc/singleton.h>
@@ -177,6 +179,12 @@ public:
         return ShutdownThreadId_.load();
         return ShutdownThreadId_.load();
     }
     }
 
 
+    void EnsureSystemInvokersRunning() const
+    {
+        NConcurrency::GetFinalizerInvoker();
+        NConcurrency::GetShutdownInvoker();
+    }
+
 private:
 private:
     std::atomic<FILE*> ShutdownLogFile_ = IsShutdownLoggingEnabledImpl() ? stderr : nullptr;
     std::atomic<FILE*> ShutdownLogFile_ = IsShutdownLoggingEnabledImpl() ? stderr : nullptr;
 
 
@@ -275,6 +283,11 @@ size_t GetShutdownThreadId()
     return TShutdownManager::Get()->GetShutdownThreadId();
     return TShutdownManager::Get()->GetShutdownThreadId();
 }
 }
 
 
+void EnsureSafeShutdown()
+{
+    TShutdownManager::Get()->EnsureSystemInvokersRunning();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
 
 static const void* ShutdownGuardInitializer = [] {
 static const void* ShutdownGuardInitializer = [] {

+ 11 - 0
yt/yt/core/misc/shutdown.h

@@ -76,6 +76,17 @@ FILE* TryGetShutdownLogFile();
 //! the id of the thread invoking shutdown callbacks.
 //! the id of the thread invoking shutdown callbacks.
 size_t GetShutdownThreadId();
 size_t GetShutdownThreadId();
 
 
+//! Some actions that are required for proper shutdown
+//! may only happen during the shutdown when they are
+//! no longer safe to be executed, e.g. system invokers
+//! creation.
+//! Call this method before |Shutdown| to make sure everything is going to work safely.
+//! This method can be called multiple times. No-op after the first call.
+//! If you encounter build timeout during codegen phase or something similar,
+//! try calling any other method from this header prior as it would break
+//! any possible recursive behaviors of static variables.
+void EnsureSafeShutdown();
+
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
 
 } // namespace NYT
 } // namespace NYT