Boost logo

Boost :

Subject: Re: [boost] [future] usage question for new accepted library
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-05-14 13:24:15


Hi,
----- Original Message -----
From: "Alan Patterson" <alan.patterson_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Thursday, May 14, 2009 1:22 PM
Subject: [boost] [future] usage question for new accepted library

>
> Hi,
> I see Anthony William's future implementation has been accepted over
> Braddock Gaskill's.
>
> I have been using Braddocks implementation and in particular a couple of
> features which I believe are not in Anthony's implementation. So I am
> looking for some pointers for how I might do the following with the
> accepted futures implementation.
>
> 1) Using the implicit cast of future<T> to T.

If I remember Braddock was not confident with this implicit conversion.
 
> I have an application where I can submit jobs to a scheduler, have them
> executed and provide me with a return value.
>
> My scheduler uses a policy for implementation:
> scheduler<single_threaded_policy>
> scheduler<threadpool_policy>
>
> The user submits a task and gets the result like
>
> result_type r = scheduler.submit(some_task());
>
> where result_type is obtained from the scheduler and can either be of
> type T for single_threaded or future<T> for threadpools.
> Either way the client doesn't care which, because he can use a T or
> future<T> identically IF future<T> casts to T.
>
> I like this because the client never knows anything about futures, he
> treats all result_types as type T.
>
> I guess the way to do this with the accepted future implementation is to
> create a template function that does the following:
>
> T actual_r = get<result_type>(r);
>
> which call get() if it is a future or just returns r if not. But this is
> no where near as nice IMHO. The user no longer just uses the result_type
> of his task directly for what seems to be a basic type.

Your scheduler can returns a class that follows the future interface but that is simplified because the value is set at construction time. So your application can get the value always in the same way

TheScheduler::result_type r = scheduler.submit(some_task());
r.get()

The Boost Async library defines a framework based on Asynchronous which allows to add a inmediate scheduler

typedef inmediate_call TheScheduler;
TheScheduler scheduler;

TheScheduler::act r = fork(scheduler, some_task());

Currently I have no defined such a inmediate scheduler. I think that it is a good idea to define one.
 
> 2) callbacks when future is set
>
> I have a usage scenario where I submit a batch of tasks where I collect
> results until I either have the result I want or collect enough that I
> can return what I have. This is neither a wait_for_any or a
> wait_for_all, more a kind of wait_until_i_have_enough.
>
> I currently implement this by submitting the batch of tasks and getting
> a batch of futures. I then register a callback on each future that gets
> called as each future gets set. The callback collects results as they
> come in and can decide to bail out early if it has enough results.
>
> How would I go about implementing this usage with the new futures
> implementation?

Your use cases needs only one callback. IMO you can wrap the task functions and do whatever yo did on the callback. E.g.

template <typename F, typename Callback>
class wrapper {
public:
    wrapper(F, ) : f_(f), callback_(callback)

    operator ()() {
        result_of<F>::type res=f_();
        callback_(res);
        return res;
    }
private:
    F f_;
    Callback callback_;
};

And submit the batch task with this wrapper.

    scheduler.submit(wrapper(some_task(), some_call_back()));

I think that the callback and the future are orthogonal. Let me know if this design works for your use case.

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk