Re: [Boost-users] [asio] How to deal with no-connect and/or read-timeout

If the timer handler is called first, then you're done: initiate disconnection, etc. If the read handler is called first, you simply reset the timer (maybe cancel and then reset). I honestly don't know if you have to worry about a race condition (timer going off while handler for async_read is executing), or if a cancel / reschedule out of the async_read handler would preempt any other handlers. You might end up having to stick both the async_read and deadline_timer in the same strand; that would prohibit concurrent execution.
There is a good example: http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/timeouts/se rver.cpp and a good article: http://blog.think-async.com/2010/04/timeouts-by-analogy.html and a rather heavy example: http://sourceforge.net/projects/asio-samples/ (see project named echo_server). In general, you will need a state machine (or even few of them). Regards, Marat Abrarov.

On Tue, Jun 25, 2013 at 10:00 AM, Marat Abrarov
If the timer handler is called first, then you're done: initiate disconnection, etc. If the read handler is called first, you simply reset the timer (maybe cancel and then reset). I honestly don't know if you have to worry about a race condition (timer going off while handler for async_read is executing), or if a cancel / reschedule out of the async_read handler would preempt any other handlers. You might end up having to stick both the async_read and deadline_timer in the same strand; that would prohibit concurrent execution.
There is a good example: http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/timeouts/se...
Hmm, reading through this one, I'm not sure we want to disconnect the socket before the service is through, unless there's a good reason, like an error code occurred; i.e. network error, client disconnected, and so on. Read will likely be idle throughout, but can occasionally receive messages. More likely we will be sending messages. Will study this one bit closer I think. I expect to host an io_service in a thread runner with mutex-protected deque of events that publish to subscribers. As has been suggested, I expect to handle the concern of: whether connected. That's one use case of this service, it can run "serverless" if needs be for diagnostic purposes. The real discipline for me is in separating the concerns: server from connection (and/or session), session from worker thread, and so on. Making sure the strands all go when I expect them to is the challenge. Session will expose a Boost.Signals2 hook that requests a next write from the hosting worker thread for the write part. Write, message content, framing, and so on, is straightforward enough. The read part is *I think* is "simple" enough, deadline-timered, read a some as long as there is something available and pass that through an framing unwrapper. If I understand the Asio model, it's all about keeping the io_service busy doing something. Maybe asynchronously waiting for the next thing, but in any event, keep running the next part (the state machine aspect).
and a good article: http://blog.think-async.com/2010/04/timeouts-by-analogy.html
and a rather heavy example: http://sourceforge.net/projects/asio-samples/ (see project named echo_server).
In general, you will need a state machine (or even few of them).
I am familiar with this concept. We've done something right along these lines for message framing. Out-bound (write/send) is simple. In-coming (read/receive), not so much: state machine. Seems like the more layers I peel back grasping this Asio animal, there's one more. However, I am growing up in it, so to speak, it's easier to comprehend.
Regards, Marat Abrarov.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Tue, Jun 25, 2013 at 2:54 PM, Michael Powell
On Tue, Jun 25, 2013 at 10:00 AM, Marat Abrarov
wrote:
In general, you will need a state machine (or even few of them).
I am familiar with this concept. We've done something right along these lines for message framing. Out-bound (write/send) is simple. In-coming (read/receive), not so much: state machine.
You might also consider using Boost.Context to manage Asio state. I think there are Context examples dealing with Asio.

2013/6/25 Nat Linden
You might also consider using Boost.Context to manage Asio state. I think there are Context examples dealing with Asio.
Instead of boost.context I would suggest using boost.fiber ( github.com/olk/boost-fiber). The lib provides user-land threads (cooperative scheduling -> context switching) and integrates into boost.asio's new async_result-feature (currently in trunk - might be available in boost-1.54). boost.fiber contains some examples dealing with async_result (examples adapted from boost.asio): timer_.expires_from_now( boost::posix_time::seconds( 3) ); std::size_t n = socket_.async_read_some( boost::asio::buffer( data), boost::fibers::asio::yield); boost::asio::async_write( socket_, boost::asio::buffer( data, n), boost::fibers::asio::yield);

On 06/26/2013 08:48 AM, Oliver Kowalke wrote:
Instead of boost.context I would suggest using boost.fiber
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?

2013/6/26 Bjorn Reese
On 06/26/2013 08:48 AM, Oliver Kowalke wrote:
Instead of boost.context I would suggest using boost.fiber
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
boost.context - low-level library, provides mechanism to switch between execution context (assembler etc.) boost.coroutine - uses boost.context, resume-and-suspend explicitly execution of coroutine-fn, for example docu show how to use a coroutine to suspend reading from a std::stream (special character was not received -> usually stream blocks) boost.fiber - uses boost.context, provides a framework like boost.thread, fibers not explicitly resumed/suspended (done by mutext/condition/barrier ...), all fibers run concurrent in the same thread Which lib you choose depends on your preferred programming model.

On Wed, Jun 26, 2013 at 5:35 AM, Oliver Kowalke
2013/6/26 Bjorn Reese
On 06/26/2013 08:48 AM, Oliver Kowalke wrote:
Instead of boost.context I would suggest using boost.fiber
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
boost.context - low-level library, provides mechanism to switch between execution context (assembler etc.) boost.coroutine - uses boost.context, resume-and-suspend explicitly execution of coroutine-fn, for example docu show how to use a coroutine to suspend reading from a std::stream (special character was not received -> usually stream blocks) boost.fiber - uses boost.context, provides a framework like boost.thread, fibers not explicitly resumed/suspended (done by mutext/condition/barrier ...), all fibers run concurrent in the same thread
I should have suggested Coroutine instead of Context. Boost.Context is a lower-level API on which to build high-level APIs such as Coroutine and Fiber. It exists as a separate library in case your high-level API needs are not met by either Coroutine or Fiber. Apologies. To my mind, there are two key distinctions between Coroutine and Fiber. As Oliver says, a coroutine is called, yields some value to its caller, and is called again with another set of parameter values. To its caller it resembles an ordinary function call. But within the coroutine, the yield operation itself behaves like a function call: you yield a value and then, on being called again, resume execution from the same point in your coroutine. This can involve arbitrary recursion; a coroutine is a straightforward way to implement, say, iterators over a tree structure. A fiber more closely resembles a thread. It runs independently of the code that launches it; communication between fibers is arranged using mechanisms that resemble inter-thread communications. It's just that context switching between fibers is massively cheaper than context switching between threads -- and two fibers *cannot* race to access the same data. While one fiber is running, you know that other fibers in the same thread are not. Therefore data shared between fibers are always in a known state. The other key distinction is that Coroutine is already an official Boost library. Fiber is "coming soon."

On Wed, Jun 26, 2013 at 7:29 AM, Nat Linden
On Wed, Jun 26, 2013 at 5:35 AM, Oliver Kowalke
wrote: 2013/6/26 Bjorn Reese
On 06/26/2013 08:48 AM, Oliver Kowalke wrote:
Instead of boost.context I would suggest using boost.fiber
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
boost.context - low-level library, provides mechanism to switch between execution context (assembler etc.) boost.coroutine - uses boost.context, resume-and-suspend explicitly execution of coroutine-fn, for example docu show how to use a coroutine to suspend reading from a std::stream (special character was not received -> usually stream blocks) boost.fiber - uses boost.context, provides a framework like boost.thread, fibers not explicitly resumed/suspended (done by mutext/condition/barrier ...), all fibers run concurrent in the same thread
I should have suggested Coroutine instead of Context. Boost.Context is a lower-level API on which to build high-level APIs such as Coroutine and Fiber. It exists as a separate library in case your high-level API needs are not met by either Coroutine or Fiber. Apologies.
To my mind, there are two key distinctions between Coroutine and Fiber.
As Oliver says, a coroutine is called, yields some value to its caller, and is called again with another set of parameter values. To its caller it resembles an ordinary function call. But within the coroutine, the yield operation itself behaves like a function call: you yield a value and then, on being called again, resume execution from the same point in your coroutine. This can involve arbitrary recursion; a coroutine is a straightforward way to implement, say, iterators over a tree structure.
Right. That's basically what we're doing now, I believe.
A fiber more closely resembles a thread. It runs independently of the code that launches it; communication between fibers is arranged using mechanisms that resemble inter-thread communications. It's just that context switching between fibers is massively cheaper than context switching between threads -- and two fibers *cannot* race to access the same data. While one fiber is running, you know that other fibers in the same thread are not. Therefore data shared between fibers are always in a known state.
I scanned over the fiber repo examples, and this does look like a compelling way to simplify the whole approach IMO.
The other key distinction is that Coroutine is already an official Boost library. Fiber is "coming soon."
There is that, which we need an approach today. I am looking forward to the Git-submodule approach in future versions of Boost, however. Far cry from the monolithic repo, but for an interest to back up local copies of all source, built or otherwise. But that's a topic for another time.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 26/06/2013 7:11 PM, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example: https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...

On Wed, Jun 26, 2013 at 10:39 AM, Arash Partow
On 26/06/2013 7:11 PM, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example:
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...
It's an asio example, but doesn't address the question about Context, Coroutine or Fiber.

On 27/06/2013, Nat Linden
On Wed, Jun 26, 2013, Arash Partow wrote:
On 26/06/2013, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example:
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...
It's an asio example, but doesn't address the question about Context, Coroutine or Fiber.
Well actually it does. The trick is to click the link, read and comprehend the code example, at which point an astute individual may realize that CK has gone to a lot of effort to integrate coroutine semantics into stock asio within the context of C++11. So then it becomes a question of: 1. Do I use another library to provide the functionality I think I may need? or 2. Should I better familiarize myself with the available facilities (which btw have been designed for the use case the library deals with) in the current library? Oh and btw the example quoted above quite clearly deals with the OP's original problem in a clean, efficient and simple to understand manner and so to the many other examples related to timeouts in the asio example set, all it takes is a bit of tinkering.

2013/6/27 Arash Partow
The trick is to click the link, read and comprehend the code example, at which point an astute individual may realize that CK has gone to a lot of effort to integrate coroutine semantics into stock asio within the context of C++11.
boost::asio:yield_context - uses internaly boost.coroutine boost::fibers::asio::yield - uses internaly boost.fiber both rely on boost.context
1. Do I use another library to provide the functionality I think I may need?
as I wrote it depends on your programming model - with coroutine-version (boost::asio:yield_context) you only operate in the asio-related context with fiber version (boost::fibers::asio::yield) you get a broader range of usage == for instance the one-thread-for-one client (10k-problem) can easliy be used with boost.fiber + boost.asio (boost::fibers::asio::yield) without degrading over-all performance (at a certain amount of threads scheduling overhead inside the OS counts + context switching between threads). you can use mutex, condition-vars .... to sync fibers etc.
Oh and btw the example quoted above quite clearly deals with the OP's original problem in a clean, efficient and simple to understand manner and so to the many other examples related to timeouts in the asio example set, all it takes is a bit of tinkering.
boost.fiber contains this example adapted to use boost.fiber

On 27/06/2013 Oliver Kowalke wrote:
boost::asio:yield_context - uses internally boost.coroutine boost::fibers::asio::yield - uses internally boost.fiber
both rely on boost.context
A completely irrelevant statement. The gist of my previous comment was not about the details of the coroutine facilities in asio, but rather the fact that said semantics were already available within the stock asio interface and that perhaps before attempting to integrate another interface/library into the OPs solution, they could attempt to see if the already available facilities in asio would meet their needs - which would include as you suggested taking into account the various performance criteria and "programming models".
you can use mutex, condition-vars .... to sync fibers etc.
boost.fiber contains this example adapted to use boost.fiber
So the old adage that good examples tend be repeated must be true! :D

2013/6/28 Arash Partow
On 27/06/2013 Oliver Kowalke wrote:
boost::asio:yield_context - uses internally boost.coroutine boost::fibers::asio::yield - uses internally boost.fiber
both rely on boost.context
A completely irrelevant statement.
tried to express that coroutines and fibers are different abstractions over the same scheduling model
The gist of my previous comment was not about the details of the coroutine facilities in asio, but rather the fact that said semantics were already available within the stock asio interface and that perhaps before attempting to integrate another interface/library into the OPs solution, they could attempt to see if the already available facilities in asio would meet their needs - which would include as you suggested taking into account the various performance criteria and "programming models".
'programming models' - event-based, multithreaded, combination of both? with boost.asio scattering your code with multiple callbacks ... the main benefit of using coroutines or fibers is that you can program your code straight forward. with the 'old' callbacks in asio you have to split your logic in multiple functions/callbacks called by the async-ops.

On Thu, Jun 27, 2013 at 11:38 PM, Oliver Kowalke
2013/6/28 Arash Partow
On 27/06/2013 Oliver Kowalke wrote:
boost::asio:yield_context - uses internally boost.coroutine boost::fibers::asio::yield - uses internally boost.fiber
both rely on boost.context
A completely irrelevant statement.
tried to express that coroutines and fibers are different abstractions over the same scheduling model
The gist of my previous comment was not about the details of the coroutine facilities in asio, but rather the fact that said semantics were already available within the stock asio interface and that perhaps before attempting to integrate another interface/library into the OPs solution, they could attempt to see if the already available facilities in asio would meet their needs - which would include as you suggested taking into account the various performance criteria and "programming models".
'programming models' - event-based, multithreaded, combination of both?
with boost.asio scattering your code with multiple callbacks ...
Yessir, precisely my observation as well. Looks like it will be so much easier to compose client/server concerns now.
the main benefit of using coroutines or fibers is that you can program your code straight forward. with the 'old' callbacks in asio you have to split your logic in multiple functions/callbacks called by the async-ops.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Wed, Jun 26, 2013 at 9:39 AM, Arash Partow
On 26/06/2013 7:11 PM, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example:
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...
Looks like that spawns a couple of strands of lambdas. The same thing could be done with member functions? We don't have an echo server, but would be reading event messages from a client in one strand, then adapting some sort of subscriber/channel pub/sub push/pull methodology to send event messages to the client. I gather with the asio io_service strand approach, that is running a couple of threads concurrently? I am noticing the steady timer shared between both strands, for instance. Thanks!
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Michael Powell wrote:
Looks like that spawns a couple of strands of lambdas.
The same thing could be done with member functions?
Yes, however when comparing this particular example to the original echo server example in asio (async), the benefits seen are predominantly centered around performance.

On Wed, Jun 26, 2013 at 9:39 AM, Arash Partow
On 26/06/2013 7:11 PM, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example:
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...
This is a different version of boost? Because I can't seem to find spawn.hpp in version 1.53 that I downloaded.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Thu, Jun 27, 2013 at 9:23 AM, Michael Powell
On Wed, Jun 26, 2013 at 9:39 AM, Arash Partow
wrote: On 26/06/2013 7:11 PM, Bjorn Reese wrote:
Could you provide some guidance about the pros and cons of Context versus Fiber versus Coroutine so that we are in a better position to select the appropriate module?
Not guidance per se but here's a nice example:
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp11/sp...
This is a different version of boost? Because I can't seem to find spawn.hpp in version 1.53 that I downloaded.
My mistake. It appears to be a 1.54 feature. Can't wait! http://www.boost.org/users/history/version_1_54_0.html
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (6)
-
Arash Partow
-
Bjorn Reese
-
Marat Abrarov
-
Michael Powell
-
Nat Linden
-
Oliver Kowalke