[event_engine+promises] EventEngine based wakeup scheduler for activities (#31926)
* eliminate activity* from wakers * event engine activity wakeup scheduler * Automated change: Fix sanity tests * add exec ctx * fix * iwyu * fix Co-authored-by: ctiller <ctiller@users.noreply.github.com>pull/32060/head
parent
bf9d7cb2fe
commit
9beb72836e
11 changed files with 317 additions and 39 deletions
@ -0,0 +1,63 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GRPC_CORE_LIB_PROMISE_EVENT_ENGINE_WAKEUP_SCHEDULER_H |
||||
#define GRPC_CORE_LIB_PROMISE_EVENT_ENGINE_WAKEUP_SCHEDULER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include <grpc/event_engine/event_engine.h> |
||||
|
||||
#include "src/core/lib/iomgr/exec_ctx.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
// A callback scheduler for activities that works by scheduling callbacks on the
|
||||
// exec ctx.
|
||||
class EventEngineWakeupScheduler { |
||||
public: |
||||
explicit EventEngineWakeupScheduler( |
||||
std::shared_ptr<grpc_event_engine::experimental::EventEngine> |
||||
event_engine) |
||||
: event_engine_(std::move(event_engine)) {} |
||||
|
||||
template <typename ActivityType> |
||||
class BoundScheduler |
||||
: public grpc_event_engine::experimental::EventEngine::Closure { |
||||
protected: |
||||
explicit BoundScheduler(EventEngineWakeupScheduler scheduler) |
||||
: event_engine_(std::move(scheduler.event_engine_)) {} |
||||
BoundScheduler(const BoundScheduler&) = delete; |
||||
BoundScheduler& operator=(const BoundScheduler&) = delete; |
||||
void ScheduleWakeup() { event_engine_->Run(this); } |
||||
void Run() final { |
||||
ApplicationCallbackExecCtx app_exec_ctx; |
||||
ExecCtx exec_ctx; |
||||
static_cast<ActivityType*>(this)->RunScheduledWakeup(); |
||||
} |
||||
|
||||
private: |
||||
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_; |
||||
}; |
||||
|
||||
private: |
||||
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_CORE_LIB_PROMISE_EVENT_ENGINE_WAKEUP_SCHEDULER_H
|
@ -0,0 +1,70 @@ |
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/core/lib/promise/event_engine_wakeup_scheduler.h" |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#include <memory> |
||||
|
||||
#include "absl/status/status.h" |
||||
#include "gtest/gtest.h" |
||||
|
||||
#include <grpc/event_engine/event_engine.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "src/core/lib/gprpp/notification.h" |
||||
#include "src/core/lib/promise/activity.h" |
||||
#include "src/core/lib/promise/poll.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
TEST(EventEngineWakeupSchedulerTest, Works) { |
||||
int state = 0; |
||||
Notification done; |
||||
auto activity = MakeActivity( |
||||
[&state]() mutable -> Poll<absl::Status> { |
||||
++state; |
||||
switch (state) { |
||||
case 1: |
||||
return Pending(); |
||||
case 2: |
||||
return absl::OkStatus(); |
||||
default: |
||||
abort(); |
||||
} |
||||
}, |
||||
EventEngineWakeupScheduler( |
||||
grpc_event_engine::experimental::CreateEventEngine()), |
||||
[&done](absl::Status status) { |
||||
EXPECT_EQ(status, absl::OkStatus()); |
||||
done.Notify(); |
||||
}); |
||||
|
||||
EXPECT_EQ(state, 1); |
||||
EXPECT_FALSE(done.HasBeenNotified()); |
||||
activity->ForceWakeup(); |
||||
done.WaitForNotification(); |
||||
EXPECT_EQ(state, 2); |
||||
} |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
grpc_init(); |
||||
auto r = RUN_ALL_TESTS(); |
||||
grpc_shutdown(); |
||||
return r; |
||||
} |
Loading…
Reference in new issue