-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
overload: create scaled timers via the dispatcher #14679
Changes from 2 commits
842d5fa
9d167b1
e39717a
cf94145
4856934
db50f12
c2e548a
58cc3c5
ec55d5f
053a315
4d6d288
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
#include "envoy/common/scope_tracker.h" | ||
#include "envoy/common/time.h" | ||
#include "envoy/event/file_event.h" | ||
#include "envoy/event/scaled_range_timer_manager.h" | ||
#include "envoy/event/schedulable_cb.h" | ||
#include "envoy/event/signal.h" | ||
#include "envoy/event/timer.h" | ||
|
@@ -77,6 +78,21 @@ class DispatcherBase { | |
*/ | ||
virtual Event::TimerPtr createTimer(TimerCb cb) PURE; | ||
|
||
/** | ||
* Allocates a scaled timer. @see Timer for docs on how to use the timer. | ||
* @param timer_type the type of timer to create. | ||
* @param cb supplies the callback to invoke when the timer fires. | ||
*/ | ||
virtual Event::TimerPtr createScaledTimer(Event::ScaledRangeTimerManager::TimerType timer_type, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to move There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I'm not attached to the placement, and I don't like how verbose the references are to it ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that callers are expected to use this on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put it in |
||
TimerCb cb) PURE; | ||
|
||
/** | ||
* Allocates a scaled timer. @see Timer for docs on how to use the timer. | ||
* @param minimum the rule for computing the minimum value of the timer. | ||
* @param cb supplies the callback to invoke when the timer fires. | ||
*/ | ||
virtual Event::TimerPtr createScaledTimer(ScaledTimerMinimum minimum, TimerCb cb) PURE; | ||
|
||
/** | ||
* Allocates a schedulable callback. @see SchedulableCallback for docs on how to use the wrapped | ||
* callback. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,12 +18,20 @@ Impl::Impl(Thread::ThreadFactory& thread_factory, Stats::Store& store, | |
process_context_(process_context), watermark_factory_(std::move(watermark_factory)) {} | ||
|
||
Event::DispatcherPtr Impl::allocateDispatcher(const std::string& name) { | ||
return std::make_unique<Event::DispatcherImpl>(name, *this, time_system_, watermark_factory_); | ||
return std::make_unique<Event::DispatcherImpl>(name, *this, time_system_, nullptr, | ||
watermark_factory_); | ||
} | ||
Event::DispatcherPtr | ||
Impl::allocateDispatcher(const std::string& name, | ||
const Event::ScaledRangeTimerManagerFactory& scaled_timer_factory) { | ||
return std::make_unique<Event::DispatcherImpl>(name, *this, time_system_, scaled_timer_factory, | ||
watermark_factory_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm trying to think about what could be done to avoid this separate API method, although I think this new method is fine. I see that Server::InstanceImpl owns both the api::Impl and the OverloadManager. OverloadManager depends on a dispatcher so it must be created well after api::Impl which is used to allocate the dispatcher. It would be useful to have Api::Impl provide the access to OverloadManager needed by the dispatcher allocation function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that would violate the expectation on API, which is that it is (roughtly) for providing platform-level functionality. Overload management doesn't feel like something on that level. |
||
} | ||
|
||
Event::DispatcherPtr Impl::allocateDispatcher(const std::string& name, | ||
Buffer::WatermarkFactoryPtr&& factory) { | ||
return std::make_unique<Event::DispatcherImpl>(name, *this, time_system_, std::move(factory)); | ||
return std::make_unique<Event::DispatcherImpl>(name, *this, time_system_, nullptr, | ||
std::move(factory)); | ||
} | ||
|
||
} // namespace Api | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
#include "common/common/thread.h" | ||
#include "common/event/file_event_impl.h" | ||
#include "common/event/libevent_scheduler.h" | ||
#include "common/event/scaled_range_timer_manager_impl.h" | ||
#include "common/event/signal_impl.h" | ||
#include "common/event/timer_impl.h" | ||
#include "common/filesystem/watcher_impl.h" | ||
|
@@ -37,17 +38,22 @@ | |
namespace Envoy { | ||
namespace Event { | ||
|
||
DispatcherImpl::DispatcherImpl(const std::string& name, Api::Api& api, | ||
Event::TimeSystem& time_system, | ||
const Buffer::WatermarkFactorySharedPtr& factory) | ||
DispatcherImpl::DispatcherImpl( | ||
const std::string& name, Api::Api& api, Event::TimeSystem& time_system, | ||
const std::function<ScaledRangeTimerManagerPtr(Dispatcher&)>& scaled_timer_factory, | ||
const Buffer::WatermarkFactorySharedPtr& watermark_factory) | ||
: name_(name), api_(api), | ||
buffer_factory_(factory != nullptr ? factory | ||
: std::make_shared<Buffer::WatermarkBufferFactory>()), | ||
buffer_factory_(watermark_factory != nullptr | ||
? watermark_factory | ||
: std::make_shared<Buffer::WatermarkBufferFactory>()), | ||
scheduler_(time_system.createScheduler(base_scheduler_, base_scheduler_)), | ||
deferred_delete_cb_(base_scheduler_.createSchedulableCallback( | ||
[this]() -> void { clearDeferredDeleteList(); })), | ||
post_cb_(base_scheduler_.createSchedulableCallback([this]() -> void { runPostCallbacks(); })), | ||
current_to_delete_(&to_delete_1_) { | ||
current_to_delete_(&to_delete_1_), | ||
scaled_timer_manager_(scaled_timer_factory != nullptr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comparing a function reference to nullptr seems a bit strange. I would suggest removing the " != nullptr" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, we can assume callers won't pass in a null function reference. |
||
? scaled_timer_factory(*this) | ||
: std::make_unique<ScaledRangeTimerManagerImpl>(*this)) { | ||
ASSERT(!name_.empty()); | ||
FatalErrorHandler::registerFatalErrorHandler(*this); | ||
updateApproximateMonotonicTimeInternal(); | ||
|
@@ -190,6 +196,17 @@ TimerPtr DispatcherImpl::createTimer(TimerCb cb) { | |
return createTimerInternal(cb); | ||
} | ||
|
||
TimerPtr DispatcherImpl::createScaledTimer(ScaledRangeTimerManager::TimerType timer_type, | ||
TimerCb cb) { | ||
ASSERT(isThreadSafe()); | ||
return scaled_timer_manager_->createTimer(timer_type, std::move(cb)); | ||
} | ||
|
||
TimerPtr DispatcherImpl::createScaledTimer(ScaledTimerMinimum minimum, TimerCb cb) { | ||
ASSERT(isThreadSafe()); | ||
return scaled_timer_manager_->createTimer(minimum, std::move(cb)); | ||
} | ||
|
||
Event::SchedulableCallbackPtr DispatcherImpl::createSchedulableCallback(std::function<void()> cb) { | ||
ASSERT(isThreadSafe()); | ||
return base_scheduler_.createSchedulableCallback([this, cb]() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,8 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>, | |
public FatalErrorHandlerInterface { | ||
public: | ||
DispatcherImpl(const std::string& name, Api::Api& api, Event::TimeSystem& time_system, | ||
const Buffer::WatermarkFactorySharedPtr& factory = nullptr); | ||
const ScaledRangeTimerManagerFactory& scaled_timer_factory = nullptr, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: prefer default constructor over nullptr when specifying default function argument There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
const Buffer::WatermarkFactorySharedPtr& watermark_factory = nullptr); | ||
~DispatcherImpl() override; | ||
|
||
/** | ||
|
@@ -67,6 +68,9 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>, | |
Network::UdpListenerPtr createUdpListener(Network::SocketSharedPtr socket, | ||
Network::UdpListenerCallbacks& cb) override; | ||
TimerPtr createTimer(TimerCb cb) override; | ||
TimerPtr createScaledTimer(ScaledRangeTimerManager::TimerType timer_type, TimerCb cb) override; | ||
TimerPtr createScaledTimer(ScaledTimerMinimum minimum, TimerCb cb) override; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to have some basic tests for these methods in dispatcher_impl_test There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
Event::SchedulableCallbackPtr createSchedulableCallback(std::function<void()> cb) override; | ||
void deferredDelete(DeferredDeletablePtr&& to_delete) override; | ||
void exit() override; | ||
|
@@ -154,6 +158,7 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>, | |
bool deferred_deleting_{}; | ||
MonotonicTime approximate_monotonic_time_; | ||
WatchdogRegistrationPtr watchdog_registration_; | ||
const ScaledRangeTimerManagerPtr scaled_timer_manager_; | ||
}; | ||
|
||
} // namespace Event | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is passing in a factory the right thing, or should we prefer passing in an std::unique_ptr ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(assuming you mean std::unique_ptr) we can't pass in a pointer because the manager is backed by the dispatcher so we can't construct one without constructing the Dispatcher first or at at the same time.