1
#pragma once
2

            
3
#include "envoy/server/overload/overload_manager.h"
4
#include "envoy/thread_local/thread_local.h"
5

            
6
#include "source/common/event/scaled_range_timer_manager_impl.h"
7

            
8
namespace Envoy {
9
namespace Server {
10

            
11
/** Implementation of OverloadManager that is never overloaded. Using this instead of the real
12
 *  OverloadManager keeps the admin interface accessible even when the proxy is overloaded.
13
 */
14
class NullOverloadManager : public OverloadManager {
15
public:
16
  struct OverloadState : public ThreadLocalOverloadState {
17
    OverloadState(Event::Dispatcher& dispatcher, bool permissive)
18
21243
        : dispatcher_(dispatcher), permissive_(permissive) {}
19
911
    const OverloadActionState& getState(const std::string&) override { return inactive_; }
20
2
    bool tryAllocateResource(OverloadProactiveResourceName, int64_t) override {
21
2
      return permissive_;
22
2
    }
23
2
    bool tryDeallocateResource(OverloadProactiveResourceName, int64_t) override {
24
2
      return permissive_;
25
2
    }
26
14
    bool isResourceMonitorEnabled(OverloadProactiveResourceName) override { return false; }
27
    ProactiveResourceMonitorOptRef
28
2
    getProactiveResourceMonitorForTest(OverloadProactiveResourceName) override {
29
2
      return makeOptRefFromPtr<ProactiveResourceMonitor>(nullptr);
30
2
    }
31
    Event::Dispatcher& dispatcher_;
32
    const bool permissive_;
33
    const OverloadActionState inactive_ = OverloadActionState::inactive();
34
  };
35

            
36
  NullOverloadManager(ThreadLocal::SlotAllocator& slot_allocator, bool permissive)
37
21456
      : tls_(slot_allocator.allocateSlot()), permissive_(permissive) {}
38

            
39
10605
  void start() override {
40
21241
    tls_->set([this](Event::Dispatcher& dispatcher) -> ThreadLocal::ThreadLocalObjectSharedPtr {
41
21241
      return std::make_shared<OverloadState>(dispatcher, permissive_);
42
21241
    });
43
10605
  }
44

            
45
466
  ThreadLocalOverloadState& getThreadLocalOverloadState() override {
46
466
    return tls_->getTyped<OverloadState>();
47
466
  }
48

            
49
2128
  LoadShedPoint* getLoadShedPoint(absl::string_view) override { return nullptr; }
50

            
51
2
  Event::ScaledRangeTimerManagerFactory scaledTimerFactory() override {
52
2
    if (!permissive_) {
53
2
      return nullptr;
54
2
    }
55
    return [](Event::Dispatcher& dispatcher) {
56
      return std::make_unique<Event::ScaledRangeTimerManagerImpl>(dispatcher, nullptr);
57
    };
58
2
  }
59

            
60
1
  bool registerForAction(const std::string&, Event::Dispatcher&, OverloadActionCb) override {
61
1
    return true;
62
1
  }
63
  void stop() override {}
64

            
65
  ThreadLocal::SlotPtr tls_;
66
  // The admin code runs in non-permissive mode, rejecting connections and
67
  // ensuring timer code is not called. Envoy mobile uses permissive mode and
68
  // does the opposite.
69
  const bool permissive_;
70
};
71

            
72
} // namespace Server
73
} // namespace Envoy