Closed HuberyFok closed 10 months ago
The behavior of coro::sleep
depends on the behavior of executors. Concretely, it depends on the implementation of Executor::after(std::chrono::duration<T,U>)
. And it is the general idea of async_simple to make the behavior configurable with the executors.
SimpleExecutor is just an Executor for testing. It is not part of libasync_simple. You need to define your own Executor.
We use SimpleExecutor + brpc TimerThread for production currently. This is an example of custom coroutine sleep.
class BGExecutor : public async_simple::executors::SimpleExecutor {
public:
static StatusOr<std::unique_ptr<BGExecutor>> NewBGExecutor(
size_t thread_num) noexcept {
auto ptr = std::make_unique<BGExecutor>(thread_num);
auto s = ptr->Init();
if (!s.ok()) {
return s;
}
return ptr;
}
~BGExecutor() override = default;
static void TimerTaskFn(void* arg) {
auto fptr = std::unique_ptr<std::function<void()>>(
static_cast<std::function<void()>*>(arg));
(*fptr)();
}
BGExecutor(size_t thread_num)
: async_simple::executors::SimpleExecutor(thread_num) {}
private:
Status Init() {
bthread::TimerThreadOptions options;
const int rc = timer_.start(&options);
// rc != 0 when pthread create failed
// CHECK_IF_RET(rc == 0, Status::Err(),
// "Init BGExecutor. start timer failed : {}. ", rc);
return Status::OK();
}
void schedule(Func func, Duration dur) override {
async_simple::Executor::Context ctx = checkout();
auto fptr = std::make_unique<std::function<void()>>(
[this, ctx, func = std::move(func)]() {
checkin(func, ctx, async_simple::ScheduleOptions{});
});
const auto sec = std::chrono::duration_cast<std::chrono::seconds>(dur);
auto ts = timespec{
.tv_sec = sec.count(),
.tv_nsec =
std::chrono::duration_cast<std::chrono::nanoseconds>(dur - sec)
.count()};
auto* args = fptr.release();
auto task_id = timer_.schedule(TimerTaskFn, args, ts);
if (unlikely(task_id == bthread::TimerThread::INVALID_TASK_ID)) {
// BG3_ERROR("schedule timer task failed");
TimerTaskFn(args);
}
}
bthread::TimerThread timer_;
};
Closed due to no more questions. Feel free to require to reopen this.
Search before asking
What happened + What you expected to happen
when i use co_await async_simple::coro::sleep(),will brock the thread, all the coroutine is stop; when add async_simple::executors::SimpleExecutor to sleep, it will use new thread;
the sleep() should be like golang time.Sleep(),use coroutine anywhere and do not create a new thread, i think you can use aiso timer to fix it.
Reproduction way
Anything else
Are you willing to submit a PR?