beast
beast copied to clipboard
HTTP example uses explicit strand : why
In https://github.com/boostorg/beast/blob/develop/example/http/server/async/http_server_async.cpp the session object uses an explicit strand. Why is this the case?
The Asio documentation says:
Where there is a single chain of asynchronous operations associated with a connection (e.g. in a half duplex protocol implementation like HTTP) there is no possibility of concurrent execution of the handlers. This is an implicit strand.
So why do we need an explicit strand?
Cheers
@vinniefalco @klemens-morgenstern
The beast::tcp_stream allows for specifying a timeout on the stream, which internally initiates a parallel async_wait on a timer for each asynchronous operation on that stream. Here is where a timeout is set in that specific example: https://github.com/boostorg/beast/blob/develop/example/http/server/async/http_server_async.cpp#L252.
Aside from that, in multi-threaded examples, not using a strand can lead to mistakes and concurrency bugs when users modify the examples for their purposes. These bugs are often silent and difficult to debug.
So i'm not using beast::tcp_stream just a normal tcp_socket. I don't need timers. So in my case, i have an implicit strand right?
Is it good practice in Asio/Beast to disregard the fact that you have an implicit strand and just use an explicit one anyway ? Doesn't that incur a performance overhead?
So i'm not using beast::tcp_stream just a normal tcp_socket. I don't need timers. So in my case, i have an implicit strand right?
Yes, If you design your application in a way that guarantees all operations on an I/O object (like asio::ip::tcp::socket) are sequential and no mutations occur after calling each initiating function, then you don't need a strand because there is no way to have two in-flight completion handlers.
Is it good practice in Asio/Beast to disregard the fact that you have an implicit strand and just use an explicit one anyway ? Doesn't that incur a performance overhead?
I would say the overhead is insignificant compared to the actual task scheduled for execution, so performance-wise, it doesn't make a difference in most applications.
Yeah safety by default is probably a good thing.