
On Tue, 01 May 2007 15:34:47 -0700, Stjepan Rajko wrote:
fi.cancel(); // cancels if not yet complete
Cancellation by cancelling the feature is a cool idea... I assume the promise can be notified that all futures have been cancelled via a callback? Speaking of... if a function call has many outstanding promises/futures (e.g., a return value and a few "out" arguments), is there a way to group those all together so that they can be cancelled as a group?
When future<T>::cancel() is called, a future_cancel exception is set in the promise which all future instances are directly or indirectly constructed from. The futures are all placed in a ready() state, with has_exception() true, and will throw future_cancel if get() or implicit conversion is invoked. You can set a simple cancel callback to clean up your side with: promise<T>::set_cancel_handler(const boost::function<void (void)> &f) Now, if you have both a return value future, and a set of OutArg futures, you can handle that in one of two ways: 1) Do nothing. A nifty feature is that when the last promise object goes out of scope before being set, all associated futures are immediately set with a "broken_promise" exception. So when you remove your copy of the promise objects, your waiting callers get a broken_promise. 2) Maintain a list of promises and cancel them all yourself with whatever exception or value you want.
5) I want a basic timeout fi.timed_wait(100 /*ms*/); if (!fi.ready()) fi.cancel();
OK, but I think similar functionality should also be added to the rpc interface - it might be useful to be able to set a flat timeout for an individual function (or all functions), and then cancel the promise in
Yeah, I'm sure you'll want a bit more power and probably a few optional parameters in your 'rpc()' call. Maybe: future<T> rpc(RpcParameterSet, F func, ARG1, ..., ARGN) You may also want to not return a future directly, but perhaps return some rpc_call_handle type which is implicitly convertable to a future. rpc_call_handle<T> rpc(...) The rpc_call_handle may have a more powerful rpc-specific interface. Since it is implicitly convertable to a future<T>, the user can either choose to ignore it and accept a simple future<T> with the above usage, or make use of the handle for whatever rpc-specific interface is needed.
I do plan to add exception transportation. Is it possible to have the future throw a custom (specified by the promise) exception? Your point 3) suggests that this is possible also.
Yes, within certain limits. Thank Peter Dimov for his exception_ptr handling. In fact, looking at my code now I think I could improve my implementation to allow throwing arbitrary exception types. This is one of those "early" areas.
7) I have both a return value and an "Out" argument: future<int> multiplied; future<int> fi = rpc(add_and_mult, 1, 2, multiplied); cout << "1+2 = " << fi << "\n"; cout << "1*2 = " << multiplied << "\n";
ATM, seems like future doesn't have a default constructor, so future<int> multiplied; doesn't compile.
Heh, sorry about that...you are correct. A future must by constructed from a promise or another future, since a default-constructed future would never get set. Options: 1) change to promise<int> multiplied; and pass the promise to the rpc call. 2) Pass the Out arg future by reference, and replace it with a future constructed from a promise which the rpc() call creates. Work-around for the lack of default constructor would be: future<int> multiplied(promise<int>()); //will immediately be set to broken_promise, but that okay. (or ask me to provide a default constructor which does this, which is probably a good idea) I don't like (1) because it blurs the divide between future holder and promise fulfiller, and breaks the broken_promise mechanism. So I guess I should add that default constructor, eh? :)
Also, if the argument was "InOut" rather than just "Out", we'll need
Well, if you use the pass-by-reference future solution above, then you COULD pass in an already-set future, and then have the rpc() call take that value and then assign the referenced future to a new promise. I'm not sure I like that though, it seems abusive and confusing.
some documentation of the features - I've been getting a lot from the code and the test cases, but sometimes the intended use escapes me.
Yes, I need to write some real documentation. :) Please continue to ask me and I will provide support. I know the implementation will benefit from it. We can move to private e-mail if you prefer (braddock@braddock.com). Braddock Gaskill Dockside Vision Inc