#include "failure_injector.h" #include #include #include namespace NYql { void TFailureInjector::Activate() { Singleton()->ActivateImpl(); } void TFailureInjector::Set(std::string_view name, ui64 skip, ui64 countOfFails) { Singleton()->SetImpl(name, skip, countOfFails); } void TFailureInjector::Reach(std::string_view name, std::function action) { Singleton()->ReachImpl(name, action); } void TFailureInjector::ActivateImpl() { Enabled_.store(true); YQL_LOG(DEBUG) << "TFailureInjector::Activate"; } THashMap TFailureInjector::GetCurrentState() { return Singleton()->GetCurrentStateImpl(); } THashMap TFailureInjector::GetCurrentStateImpl() { THashMap copy; with_lock(Lock) { copy = FailureSpecs; } return copy; } void TFailureInjector::ReachImpl(std::string_view name, std::function action) { if (!Enabled_.load()) { return; } with_lock(Lock) { if (auto failureSpec = FailureSpecs.FindPtr(name)) { YQL_LOG(DEBUG) << "TFailureInjector::Reach: " << name << ", Skip=" << failureSpec->Skip << ", Fails=" << failureSpec->CountOfFails; if (failureSpec->Skip > 0) { --failureSpec->Skip; } else if (failureSpec->CountOfFails > 0) { YQL_LOG(DEBUG) << "TFailureInjector::OnReach: " << name; --failureSpec->CountOfFails; action(); } } } } void TFailureInjector::SetImpl(std::string_view name, ui64 skip, ui64 countOfFails) { with_lock(Lock) { YQL_ENSURE(countOfFails > 0, "failure " << name << ", 'countOfFails' must be positive"); FailureSpecs[TString{name}] = TFailureSpec{skip, countOfFails}; } } } // NYql