beast icon indicating copy to clipboard operation
beast copied to clipboard

HTTP example uses explicit strand : why

Open pfeatherstone opened this issue 1 year ago • 5 comments

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

pfeatherstone avatar Jun 11 '24 08:06 pfeatherstone

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.

ashtum avatar Jun 11 '24 08:06 ashtum

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?

pfeatherstone avatar Jun 11 '24 10:06 pfeatherstone

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?

pfeatherstone avatar Jun 11 '24 10:06 pfeatherstone

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.

ashtum avatar Jun 11 '24 11:06 ashtum

Yeah safety by default is probably a good thing.

pfeatherstone avatar Jun 11 '24 11:06 pfeatherstone