Skip to content

Commit 9802ce9

Browse files
dispatcher: expose evwatch registration (#46163)
#46101 added an API to dynamically register evwatch hooks into a libevent scheduler. This PR just exposes the API via the dispatcher. Risk Level: none (not yet used) Testing: unit test added, underlying LibeventScheduler impl has its own tests Signed-off-by: antoniovleonti <leonti@google.com>
1 parent 1d2e390 commit 9802ce9

7 files changed

Lines changed: 55 additions & 0 deletions

File tree

envoy/event/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ envoy_cc_library(
2424
deps = [
2525
":deferred_deletable",
2626
":dispatcher_thread_deletable",
27+
":evwatch_interface",
2728
":file_event_interface",
2829
":scaled_timer",
2930
":schedulable_cb_interface",

envoy/event/dispatcher.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "envoy/common/scope_tracker.h"
99
#include "envoy/common/time.h"
1010
#include "envoy/event/dispatcher_thread_deletable.h"
11+
#include "envoy/event/evwatch.h"
1112
#include "envoy/event/file_event.h"
1213
#include "envoy/event/scaled_timer.h"
1314
#include "envoy/event/schedulable_cb.h"
@@ -157,6 +158,15 @@ class Dispatcher : public DispatcherBase, public ScopeTracker {
157158
virtual void registerWatchdog(const Server::WatchDogSharedPtr& watchdog,
158159
std::chrono::milliseconds min_touch_interval) PURE;
159160

161+
/**
162+
* Registers an Evwatch observer with this dispatcher.
163+
* This should only be called on the dispatcher's thread.
164+
* @param observer supplies the observer to register.
165+
* @return Evwatch::ObserverHandlePtr handle that automatically unregisters the observer when
166+
* destroyed.
167+
*/
168+
virtual Evwatch::ObserverHandlePtr registerEvwatchObserver(Evwatch::ObserverPtr observer) PURE;
169+
160170
/**
161171
* Returns a time-source to use with this dispatcher.
162172
*/

source/common/event/dispatcher_impl.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ void DispatcherImpl::registerWatchdog(const Server::WatchDogSharedPtr& watchdog,
9898
std::make_unique<WatchdogRegistration>(watchdog, *scheduler_, min_touch_interval, *this);
9999
}
100100

101+
Evwatch::ObserverHandlePtr DispatcherImpl::registerEvwatchObserver(Evwatch::ObserverPtr observer) {
102+
ASSERT(isThreadSafe());
103+
return base_scheduler_.registerEvwatchObserver(std::move(observer));
104+
}
105+
101106
void DispatcherImpl::initializeStats(Stats::Scope& scope,
102107
const std::optional<std::string>& prefix) {
103108
const std::string effective_prefix = prefix.has_value() ? *prefix : absl::StrCat(name_, ".");

source/common/event/dispatcher_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>,
5959
const std::string& name() override { return name_; }
6060
void registerWatchdog(const Server::WatchDogSharedPtr& watchdog,
6161
std::chrono::milliseconds min_touch_interval) override;
62+
Evwatch::ObserverHandlePtr registerEvwatchObserver(Evwatch::ObserverPtr observer) override;
6263
TimeSource& timeSource() override { return time_source_; }
6364
void initializeStats(Stats::Scope& scope, const std::optional<std::string>& prefix) override;
6465
void clearDeferredDeleteList() override;

test/common/event/dispatcher_impl_test.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,35 @@ TEST_F(DispatcherConnectionTest, CreateEnvoyInternalConnectionWhenFactoryNotExis
15251525
"");
15261526
}
15271527

1528+
TEST(EvwatchObserverTest, RegisterEvwatchObserver) {
1529+
class MockEvwatchObserver : public Evwatch::Observer {
1530+
public:
1531+
MOCK_METHOD(void, onPrepare,
1532+
(MonotonicTime prepare_time, std::optional<MonotonicTime::duration> timeout));
1533+
MOCK_METHOD(void, onCheck, (MonotonicTime check_time));
1534+
};
1535+
1536+
Api::ApiPtr api = Api::createApiForTest();
1537+
DispatcherPtr dispatcher = api->allocateDispatcher("test_thread");
1538+
1539+
EXPECT_EQ(nullptr, dispatcher->registerEvwatchObserver(nullptr));
1540+
1541+
auto observer = std::make_unique<NiceMock<MockEvwatchObserver>>();
1542+
auto* observer_ptr = observer.get();
1543+
1544+
EXPECT_CALL(*observer_ptr, onPrepare(_, _)).Times(testing::AtLeast(1));
1545+
EXPECT_CALL(*observer_ptr, onCheck(_)).Times(testing::AtLeast(1));
1546+
1547+
auto handle = dispatcher->registerEvwatchObserver(std::move(observer));
1548+
EXPECT_NE(nullptr, handle);
1549+
1550+
auto cb = dispatcher->createSchedulableCallback([]() {});
1551+
cb->scheduleCallbackCurrentIteration();
1552+
dispatcher->run(Dispatcher::RunType::NonBlock);
1553+
1554+
handle.reset();
1555+
}
1556+
15281557
} // namespace
15291558
} // namespace Event
15301559
} // namespace Envoy

test/mocks/event/mocks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,14 @@ class MockDispatcher : public Dispatcher {
114114
return SignalEventPtr{listenForSignal_(signal_num, cb)};
115115
}
116116

117+
Evwatch::ObserverHandlePtr registerEvwatchObserver(Evwatch::ObserverPtr observer) override {
118+
return Evwatch::ObserverHandlePtr{registerEvwatchObserver_(observer.get())};
119+
}
120+
117121
// Event::Dispatcher
118122
MOCK_METHOD(void, registerWatchdog,
119123
(const Server::WatchDogSharedPtr&, std::chrono::milliseconds));
124+
MOCK_METHOD(Evwatch::ObserverHandle*, registerEvwatchObserver_, (Evwatch::Observer * observer));
120125
MOCK_METHOD(void, initializeStats, (Stats::Scope&, const std::optional<std::string>&));
121126
MOCK_METHOD(void, clearDeferredDeleteList, ());
122127
MOCK_METHOD(Network::ServerConnection*, createServerConnection_, (StreamInfo::StreamInfo & info));

test/mocks/event/wrapped_dispatcher.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class WrappedDispatcher : public Dispatcher {
2525
impl_.registerWatchdog(watchdog, min_touch_interval);
2626
}
2727

28+
Evwatch::ObserverHandlePtr registerEvwatchObserver(Evwatch::ObserverPtr observer) override {
29+
return impl_.registerEvwatchObserver(std::move(observer));
30+
}
31+
2832
TimeSource& timeSource() override { return impl_.timeSource(); }
2933

3034
void initializeStats(Stats::Scope& scope, const std::optional<std::string>& prefix) override {

0 commit comments

Comments
 (0)