This document will give a brief introduction of high order APIs of c++ worker, however i think Python and Java should also provide similar APIs.
These are the APIs:
API
template<typename F, typename... Args>
auto async(F&& f, Args&&... args)-> boost::unique_future<decltype(f(args...))>
Description
lauch an async operation with arbitrary arguments in a new thread, return a future object; The future object is a continuable, can be continued with the 'then' API.
enum launch{
async = 1, //in new thread
deferred = 2, //in the same thead
executor = 4, //in thread pool
};
template<typename F, typename... Args>
auto async(launch policy, F&& f, Args&&... args)-> boost::unique_future<decltype(f(args...))>
Description
Policy-based lauch an async operation with arbitrary arguments in a new thread, return a future object; The future object is a continuable, can be continued with the 'then' API.
API
template<typename Executor, typename F, typename... Args>
auto async(Executor& ex, F&& f, Args&&... args)-> boost::unique_future<decltype(f(args...))>
Description
lauch an async operation with arbitrary arguments in a given thread_pool, return a future object;
API
template<typename F>
auto future<R>::then(F&& func) -> boost::unique_future<typename boost::result_of<F(boost::unique_future)>::type>;
Description
A member function of future, used to continue the future in a chain. lauch an async operation with parant future as argument, return a future object.
API
enum launch{
async = 1, //in new thread
deferred = 2, //in the same thead
executor = 4, //in thread pool
};
template<typename F>
auto future<R>::then(launch policy, F&& func) -> boost::unique_future<typename boost::result_of<F(boost::unique_future)>::type>;
Description
A member function of future, used to continue the future in a chain. Policy-based lauch an async operation with parant future as argument, return a future object.
API
template<typename... F>
auto when_all(F... fns);
Description
Combine arbitrary futures, return a future object which will wait for all the futures finished.
API
template<typename InputIterator>
auto when_all(InputIterator first, InputIterator end);
Description
Combine many futures from a container, such as vector/list, return a future object which will wait for all the futures finished.
similar with when_all, when_any return a future object will wait for any of the futures.
TEST(RayApiTest, ThenTest){
auto future = async(Plus1, 2)
.then([](Future<int> f){
return f.get();
})
.then([](Future<int> f){
return f.get() + async(Plus, 2, 3).get();
});
EXPECT_EQ(8, future.get());
}
TEST(RayApiTest, ThenExecutorTest){
thread_pool ex;
auto future = async(ex, Plus1, 2)
.then(ex, [](Future<int> f){
return f.get();
})
.then(ex, [](Future<int> f){
return f.get() + async(Plus, 2, 3).get();
});
EXPECT_EQ(8, future.get());
}
TEST(RayApiTest, ThenWaitTest){
auto future = async(Plus1, 2)
.then([](Future<int> f){
return f.get();
})
.then([](Future<int> f){
return f.get() + async(Plus, 2, 3).get();
});
auto status = future.wait_for(boost::chrono::milliseconds(1000));
if(status==boost::future_status::ready){
EXPECT_EQ(8, future.get());
}
}
TEST(RayApiTest, WhenAllVarTest) {
auto f = boost::when_all(async(Return1), async(Plus1, 3), async(Plus, 2, 3));
auto future = f.then([](decltype(f) fu) {
auto t = fu.get();
EXPECT_TRUE(std::get<0>(t).is_ready());
EXPECT_TRUE(std::get<1>(t).is_ready());
EXPECT_TRUE(std::get<2>(t).is_ready());
});
future.get();
}
TEST(RayApiTest, WhenAllTest) {
std::vector<boost::unique_future<int>> v;
v.push_back(async(Return1));
v.push_back(async(Plus1, 3));
v.push_back(async(Plus, 2, 3));
auto f = boost::when_all(v.begin(), v.end());
auto f1 = f.then([](decltype(f) fu) {
auto v = fu.get();
for (auto& t : v) {
EXPECT_TRUE(t.is_ready());
}
});
f1.get();
}
TEST(RayApiTest, WhenAnyTest) {
std::vector<boost::unique_future<int>> v;
v.push_back(async(Return1));
v.push_back(async(Plus1, 3));
v.push_back(async(Plus, 2, 3));
auto f = boost::when_any(v.begin(), v.end());
auto future = f.then([](decltype(f) fu) {
auto v = fu.get();
bool r = false;
for (auto& t : v) {
r|=t.is_ready();
}
EXPECT_TRUE(r);
});
future.get();
}