aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/utils/failure_injector/failure_injector.cpp
blob: 4f4f9c1eb696fdd327cc66aad309828193a1d8ba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "failure_injector.h"

#include <yql/essentials/utils/log/log.h>
#include <yql/essentials/utils/yql_panic.h>

#include <util/generic/singleton.h>

namespace NYql {

void TFailureInjector::Activate() {
    Singleton<TFailureInjector>()->ActivateImpl();
}

void TFailureInjector::Set(std::string_view name, ui64 skip, ui64 countOfFails) {
    Singleton<TFailureInjector>()->SetImpl(name, skip, countOfFails);
}

void TFailureInjector::Reach(std::string_view name, std::function<void()> action) {
    Singleton<TFailureInjector>()->ReachImpl(name, action);
}

void TFailureInjector::ActivateImpl() {
    Enabled_.store(true);
    YQL_LOG(DEBUG) << "TFailureInjector::Activate";
}

THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentState() {
    return Singleton<TFailureInjector>()->GetCurrentStateImpl();
}

THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentStateImpl() {
    THashMap<TString, TFailureInjector::TFailureSpec> copy;
    with_lock(Lock) {
        copy = FailureSpecs;
    }
    return copy;
}

void TFailureInjector::ReachImpl(std::string_view name, std::function<void()> 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