failure_injector.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #include "failure_injector.h"
  2. #include <yql/essentials/utils/log/log.h>
  3. #include <yql/essentials/utils/yql_panic.h>
  4. #include <util/generic/singleton.h>
  5. namespace NYql {
  6. void TFailureInjector::Activate() {
  7. Singleton<TFailureInjector>()->ActivateImpl();
  8. }
  9. void TFailureInjector::Set(std::string_view name, ui64 skip, ui64 countOfFails) {
  10. Singleton<TFailureInjector>()->SetImpl(name, skip, countOfFails);
  11. }
  12. void TFailureInjector::Reach(std::string_view name, std::function<void()> action) {
  13. Singleton<TFailureInjector>()->ReachImpl(name, action);
  14. }
  15. void TFailureInjector::ActivateImpl() {
  16. Enabled_.store(true);
  17. YQL_LOG(DEBUG) << "TFailureInjector::Activate";
  18. }
  19. THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentState() {
  20. return Singleton<TFailureInjector>()->GetCurrentStateImpl();
  21. }
  22. THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentStateImpl() {
  23. THashMap<TString, TFailureInjector::TFailureSpec> copy;
  24. with_lock(Lock) {
  25. copy = FailureSpecs;
  26. }
  27. return copy;
  28. }
  29. void TFailureInjector::ReachImpl(std::string_view name, std::function<void()> action) {
  30. if (!Enabled_.load()) {
  31. return;
  32. }
  33. with_lock(Lock) {
  34. if (auto failureSpec = FailureSpecs.FindPtr(name)) {
  35. YQL_LOG(DEBUG) << "TFailureInjector::Reach: " << name << ", Skip=" << failureSpec->Skip << ", Fails=" << failureSpec->CountOfFails;
  36. if (failureSpec->Skip > 0) {
  37. --failureSpec->Skip;
  38. } else if (failureSpec->CountOfFails > 0) {
  39. YQL_LOG(DEBUG) << "TFailureInjector::OnReach: " << name;
  40. --failureSpec->CountOfFails;
  41. action();
  42. }
  43. }
  44. }
  45. }
  46. void TFailureInjector::SetImpl(std::string_view name, ui64 skip, ui64 countOfFails) {
  47. with_lock(Lock) {
  48. YQL_ENSURE(countOfFails > 0, "failure " << name << ", 'countOfFails' must be positive");
  49. FailureSpecs[TString{name}] = TFailureSpec{skip, countOfFails};
  50. }
  51. }
  52. } // NYql