
On Jul 29, 2011, at 7:39 PM, Jose wrote:
I would like to know if I am barking up the right tree here and if anyone has any feedback. If someone has a real project they would like to see this code incorporated into I would be more than willing to focus my development effort toward those needs.
The three libraries look really useful. The documentation is clear but a bit sparse.
There is so much to cover. I never got around to discussing how CMT does priority scheduling or too much detail into how real multi-threading works.
RPC lib: - Can you compare yours to other widely used libraries, e.g.Thrift
1) No code generation required (best for C++ to C++, but with a proper JSON interface can communicate with any language) - eliminate extra build steps - changing your code or structs in one spot applies every where. - expose any existing code as an RPC service in a non-intrusive manner. 2) Asynchronous operations performed via futures - Boost.CMT allows simple single-threaded programs to appear multi-threaded. - Benefits of async, with ease of use of synchronous code. - No need to have a real OS thread per 'async operation' nor block an OS thread waiting on a result. 3) Clean syntax, minimal macro usage 4) Automatic stubs, complete with full type erasure provided by boost::reflect::any_ptr<> - expose the same interface over JSON-RPC/TCP/UDP/HTTP, XML-RPC, protocol buffers, boost::serialization, etc - your algorithms interface with boost::reflect::any_ptr<> and so do not care if they are dealing with an RPC stub a local object, or a local actor running in a separate thread. 5) boost::signals over RPC 6) Asynchronous RPC call: Assuming you are using the mirror delegate then everything looks synchronous, but can be made asynchronous using boost::cmt boost::any_ptr<Interface> client_ptr; boost::cmt::async<ReturnType>( boost::bind(client_ptr->method_name, arg1, arg2 ) ).wait( timeout ); I have not yet implemented it, but boost::cmt::actor_interface will adapt all of the methods on an interface to return a future<> instead of the real return value. Thus: boost::any_ptr<Interface,boost::cmt::actor_interface> client_ptr; future<ReturnType> r = client_ptr->method_name( arg1, arg2 ); And of course, future<ReturnType> automatically casts to ReturnType and blocks (yields) if necessary. Then I would have a boost::actor_ptr<Interface> that could cast to and from a boost::any_ptr<Interface>. I am torn about making boost::cmt depend upon boost::reflect vs introducing yet another library called boost::actor and then having boost::rpc depend upon boost::actor.
CMT lib: - Can you compare your library to the use of coroutines in the Boostcon 2011 example https://github.com/chriskohlhoff/awesome
Awesome appears to provide stackless coroutines whereas CMT uses Boost.Context to provide a real stack per fiber.
- Could you provide a more real-life example, e.g. a proxy like in the above example ?
I use 'coroutines/fibers/futures' any time I need to perform an asynchronous operation and then it turns into a "synchronous" operation where all 'in-flight' tasks are multi-plexed on one real thread. When I actually want to do things in 'parallel' I use boost::cmt::async() and get the return value as a future. So I could enqueue 10 tasks, then wait for 10 results. I often spawn a long-running task that exits with a signal/flag and I 'join' it by waiting on its future. Other things I do is have one fiber 'wait' on a boost::signal for a value from another fiber. Lastly, any time I need to do inter-thread communication, I get the 'cmt::thread' and schedule an async task. The result is that all of my code is thread-safe and lock-free as long as the shared resource is only accessed from one thread with other threads delegating queries to it. (Much like boost::asio::strand keeps things 'thread safe'). The only thing I need to be careful about is long-running tasks that do not yield. They can block all other tasks in a particular thread. With boost CMT it is easy enough to spawn these tasks off into a real thread. I try to avoid any blocking system calls as they stall not only the current fiber, but all other tasks assigned to that thread.
- Can you provide an example that shows how to handle timeouts ?
cmt::future<ReturnType> f = boost::cmt::async<ReturnType>( Functor, priority ); try { ReturnType r = f.wait( timeout_us); } catch( const boost::cmt::future_wait_timeout& e ) { .. handle timeout here.... }
thanks jose _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost