Skip to content
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

Question why steady_timer callback happens right away #4

Closed
rbresalier opened this issue Nov 1, 2021 · 3 comments
Closed

Question why steady_timer callback happens right away #4

rbresalier opened this issue Nov 1, 2021 · 3 comments

Comments

@rbresalier
Copy link

Hi:

To test mixing generic asio with asio-grpc I did the following:

I modified hello-world-server-cpp20.cpp to add a steady_timer that would call an asynchronous timer callback 5 seconds after the server gets the request.

But the timer callback is getting called right away, not waiting 5 seconds. I tried this without asio-grpc following the boost tutorial and it does delay 5 seconds: https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio/tutorial/tuttimer2/src.html

So I added the 3 lines below marked with a *:

...
                bool request_ok = co_await agrpc::request(&helloworld::Greeter::AsyncService::RequestSayHello, service,
                                                          server_context, request, writer);
*               printf("Got request\n");
*               boost::asio::steady_timer t(grpc_context, boost::asio::chrono::seconds(5));
*               t.async_wait(&timer_callback);
                if (!request_ok)
                {
                    co_return;
                }
...

My timer_callback() is simply this:

void timer_callback(const boost::system::error_code& /*e*/)
{
  printf("Inside timer callback\n");
}

When I launch the client and it sends the request then the timer callback is immediately called and it doesn't wait 5 seconds.

Do you have any idea why? Is there a problem using asio-grpc with steady_timer?

@Tradias
Copy link
Owner

Tradias commented Nov 1, 2021

asio-grpc works correctly with steady_timer. Given your code snippet I assume that the object t goes out of scope before its deadline expires causing immediate invocation of the timer_callback. You can either do:

    auto t = std::make_unique<boost::asio::steady_timer>(grpc_context, boost::asio::chrono::seconds(5));
    auto& timer = *t;
    timer.async_wait(
        [t = std::move(t)](const boost::system::error_code& ec)
        {
            timer_callback(ec);
        });

or even better, since you already seem to be inside of a coroutine:

    boost::system::error_code ec;
    co_await timer.async_wait(asio::redirect_error(asio::use_awaitable, ec));

Also note, when you create a steady_timer Asio will create an io_context and run it on a background thread. That is rather inefficient. You can instead create a timer for the GrpcContext like so:

    grpc::Alarm alarm;
    bool timer_ran_to_completion =
        co_await agrpc::wait(alarm, boost::asio::chrono::system_clock::now() + boost::asio::chrono::seconds(5));

or again using callback style:

    auto t = std::make_unique<grpc::Alarm>();
    auto& timer = *t;
    agrpc::wait(timer, boost::asio::chrono::system_clock::now() + boost::asio::chrono::seconds(5),
                asio::bind_executor(grpc_context,
                                    [t = std::move(t)](bool timer_ran_to_completion)
                                    {
                                        timer_callback(timer_ran_to_completion);
                                    }));

@rbresalier
Copy link
Author

@Tradias : Thanks so much for your answer! Indeed I was going out of scope due to my timer being in the while loop's scope, stupid mistake, I should have known better. After fixing that it does indeed work properly. But still glad I asked this because you gave me even more useful information in your response! Thanks so much for your work here, and I know I will have more questions. I'm assuming opening an issue is the right way to ask a question, so I'll ask my next one this way, unless you tell me otherwise.

@Tradias
Copy link
Owner

Tradias commented Nov 2, 2021

Yes please continue to open issues for questions. I must say I am new to managing an open source project like this and am open to suggestions on how to better interact with the community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants