[asio] Synchronous/Asynchronous pattern

In an application we would like to support synchronous operations in the application layer, whereas operations below it are done with asynchronous operations. Callback handlers are not appropriate in this case, To make the example more clear, suppose you have a remote_vector which you would like to iterate through, remote_vector a(10); for( int i=0; i<10; ++i ) { std::cout << a[i] << std::endl; } here, a[i] will cause messages to be sent to retrieve the actual vector data before printing it. The network layer is hidden from the user. What is the best way to "emulate" synchronous behaviour with asio? The thread running this iteration should not block, but do other work (at the io_service?) until the requested results are received. Many thanks, Kind regards, Rutger ter Borg

What is the best way to "emulate" synchronous behaviour with asio? The thread running this iteration should not block, but do other work (at the io_service?) until the requested results are received.
Probably, I misunderstood you, but aren't these 2 requirements contradicting? If you wish synchronous processing of messages, then each iteration in your loop should block and wait until the i/o is done.

Igor R wrote:
What is the best way to "emulate" synchronous behaviour with asio? The thread running this iteration should not block, but do other work (at the io_service?) until the requested results are received.
Probably, I misunderstood you, but aren't these 2 requirements contradicting? If you wish synchronous processing of messages, then each iteration in your loop should block and wait until the i/o is done.
I would like to "fake" the completion handler. I have managed to get something like it working, see below. void handle_request() { result_available = false; async_write( ... request ); // .. and more async-stuf // do other stuff, fake a blocking wait while ( !result_available ) { m_io_sevice.run_one(); } return result; } void handle_read() { ... result_available = true; } bool result_available; However, I'm not sure whether to choose of poll_one or run_one in this case. I.e., I'm looking for the cheapest "do some other stuff" of asio's io_service. Cheers, Rutger

However, I'm not sure whether to choose of poll_one or run_one in this case. I.e., I'm looking for the cheapest "do some other stuff" of asio's io_service.
run_once() is ok here, but anyway your loop will *block* any further iterations until result_available == true, won't it? If so, why not just use synchronous asio functions? Actually, they are already implemented in the very similar way to what you're trying to do.

Igor R wrote:
However, I'm not sure whether to choose of poll_one or run_one in this case. I.e., I'm looking for the cheapest "do some other stuff" of asio's io_service.
run_once() is ok here, but anyway your loop will *block* any further iterations until result_available == true, won't it? If so, why not just use synchronous asio functions? Actually, they are already implemented in the very similar way to what you're trying to do.
Thanks. I'm aware of asio's synchronous operation support. However, the application in question implements a producer/consumer pattern, with potentially many blocking consumers at the same time in the same application. Other work should be done while "blocking", to keep as many threads as possible going. Why is run_one better than poll_one in this case? Thanks, Kind regards, Rutger

Igor R wrote:
What is the best way to "emulate" synchronous behaviour with asio? The thread running this iteration should not block, but do other work (at the io_service?) until the requested results are received.
Probably, I misunderstood you, but aren't these 2 requirements contradicting? If you wish synchronous processing of messages, then each iteration in your loop should block and wait until the i/o is done.
I would like to "fake" the completion handler. I have managed to get something like it working, see below. void handle_request() { result_available = false; async_write( ... request ); // .. and more async-stuf // do other stuff, fake a blocking wait while ( !result_available ) { m_io_sevice.run_one(); } return result; } void handle_read() { ... result_available = true; } bool result_available; However, I'm not sure whether to choose of poll_one or run_one in this case. I.e., I'm looking for the cheapest "do some other stuff" of asio's io_service. Cheers, Rutger

Rutger ter Borg wrote:
In an application we would like to support synchronous operations in the application layer, whereas operations below it are done with asynchronous operations. Callback handlers are not appropriate in this case,
To make the example more clear, suppose you have a remote_vector which you would like to iterate through,
remote_vector a(10); for( int i=0; i<10; ++i ) { std::cout << a[i] << std::endl; }
here, a[i] will cause messages to be sent to retrieve the actual vector data before printing it. The network layer is hidden from the user.
What is the best way to "emulate" synchronous behaviour with asio? The thread running this iteration should not block, but do other work (at the io_service?) until the requested results are received.
I don't really understand the requirement but I think it boils down to whether the other work you want to do is coupled to the async network i/o or not. If it isn't then surely that can just be done in it's own thread and the network i/o can simply be synchronous. If it is then I would use a pair of condition variables to pass commands and results between a "synchronous" layer to an "asynchronous" layer which are just 2 separate threads. If there is no pending asynchronous event to keep the io service alive then there are documented ways of dealing with this using the io_service::work object.
Many thanks, Kind regards,
Rutger ter Borg
HTH -- Bill Somerville
participants (3)
-
Bill Somerville
-
Igor R
-
Rutger ter Borg