Re: [boost] Asynchronous library now in Boost Library Incubator
After having a deeper dive into the documentation and examples, one pattern I see popping up quite frequently is this: future<R> fut = my_promise.get_future(); post_callback(some_work, [this](expected<R> r) { this->my_promise.set_value(r.get()); }); return fut;
This is simply to make examples easier to run (it finishes the example). It demonstrates that the only one which blocks in an application built on Asynchronous is main(). This might be more confusing than useful and I probably should get rid of this.
Is there any performance/usability drawback from this (might have gotten the syntax wrong here): return post_future(pool, some_work);
Why is the former to be preferred to the latter, or vice versa?
post_future is the preferred for simple applications or examples. It is similar to std::async (without the problem of blocking futures and with different continuations). post_callback is the design the library seeks to promote for bigger applications: post a task to a threadpool, get a callback posted to the queue of the caller's thread world.
Regarding the documentation overall, it seems to miss a proper reference section. For example, boost::asynchronous::expected is used almost everywhere, but not documented.
My bad. Will be corrected. Thanks, Christophe
On Mittwoch, 30. November 2016 21:47:34 CET Christophe Henry wrote:
After having a deeper dive into the documentation and examples, one pattern I see popping up quite frequently is this: future<R> fut = my_promise.get_future(); post_callback(some_work, [this](expected<R> r) { this->my_promise.set_value(r.get()); }); return fut;
This is simply to make examples easier to run (it finishes the example). It demonstrates that the only one which blocks in an application built on Asynchronous is main(). This might be more confusing than useful and I probably should get rid of this.
Understood. It's always a difficult task to present clear and good examples and best practices. Out of curiosity (I can't recall reading that in the documentation, correct me if I am wrong), how is a real and complex application supposed to signal shutdown/completion? The answer to this question is somehow important. You make it very clear, in the documentation and here in this thread, that having a chain of future.then (which conceptually really are just callbacks that are called whenever the future became ready), is not the way to go because eventually you need to block the thread of execution. At least as your very last call main, for example. Joining the threads of your active threadpools also blocks the thread of execution. So where is the difference? Which technique did I miss?
On 11/30/2016 10:27 PM, Thomas Heller wrote:
On Mittwoch, 30. November 2016 21:47:34 CET Christophe Henry wrote:
After having a deeper dive into the documentation and examples, one pattern I see popping up quite frequently is this: future<R> fut = my_promise.get_future(); post_callback(some_work, [this](expected<R> r) { this->my_promise.set_value(r.get()); }); return fut;
This is simply to make examples easier to run (it finishes the example). It demonstrates that the only one which blocks in an application built on Asynchronous is main(). This might be more confusing than useful and I probably should get rid of this.
Understood. It's always a difficult task to present clear and good examples and best practices.
Out of curiosity (I can't recall reading that in the documentation, correct me if I am wrong), how is a real and complex application supposed to signal shutdown/completion? The answer to this question is somehow important. You make it very clear, in the documentation and here in this thread, that having a chain of future.then (which conceptually really are just callbacks that are called whenever the future became ready), is not the way to go because eventually you need to block the thread of execution. At least as your very last call main, for example. Joining the threads of your active threadpools also blocks the thread of execution. So where is the difference? Which technique did I miss?
I know two ways: - adding a SIGKILL handler (posix). In that case, the main simply has to destroy the proxys it keeps alive. This will cause the matching servants to be destroyed, which will trigger the proxies held by these servants to be destroyed, etc. When none of them holds any threadpool alive, they will be destroyed too. In any case, all outstanding tasks will be executed so that no memory or resource leak occurs due to unfinished tasks. - as in the examples. The Servants held by main return a future, main waits for it. When the servants want to die (for example due to a button in a UI), they set the corresponding promise. Then happens same as above. The difference is important for sizeable applications. In these applications we have not one chain of tasks but thousands. Possibly blocking on them is complicated to handle. Using asynchronous, the only one blocking is main. This is quite a difference. Of course, if your whole application is one big functional programming model, it makes no difference. I however doubt most of us want this. As I wrote here (https://htmlpreview.github.io/?https://github.com/henry-ch/asynchronous/blob...) I disagree on the idea that a chain of futures is the same as callbacks. Cheers, Christophe
participants (2)
-
Christophe Henry
-
Thomas Heller