Commit 0f6e3043 authored by Hans Fugal's avatar Hans Fugal Committed by Alecs King

Future::ensure

Summary: Unconditionally execute the action, passthrough semantics.

Test Plan: new unit test

Reviewed By: bmatheny@fb.com

Subscribers: trunkagent, exa, folly-diffs@, yfeldblum, jsedgwick

FB internal diff: D1868837

Tasks: 6166860

Signature: t1:1868837:1424820181:0e83f54b59d7091dac60ab65feb387992e8ae89c
parent e58f1ced
......@@ -290,6 +290,16 @@ Future<T>::onError(F&& func) {
return f;
}
template <class T>
template <class F>
Future<T> Future<T>::ensure(F func) {
MoveWrapper<F> funcw(std::move(func));
return this->then([funcw](Try<T>&& t) {
(*funcw)();
return makeFuture(std::move(t));
});
}
template <class T>
template <class F>
Future<T> Future<T>::onTimeout(Duration dur, F&& func, Timekeeper* tk) {
......
......@@ -342,6 +342,13 @@ class Future {
Future<T>>::type
onError(F&& func);
/// func is like std::function<void()> and is executed unconditionally, and
/// the value/exception is passed through to the resulting Future.
/// func shouldn't throw, but if it does it will be captured and propagated,
/// and discard any value/exception that this Future has obtained.
template <class F>
Future<T> ensure(F func);
/// Like onError, but for timeouts. example:
///
/// Future<int> f = makeFuture<int>(42)
......
......@@ -1317,3 +1317,15 @@ TEST(Future, via_then_get_was_racy) {
ASSERT_TRUE(!!val);
EXPECT_EQ(42, *val);
}
TEST(Future, ensure) {
size_t count = 0;
auto cob = [&]{ count++; };
auto f = makeFuture(42)
.ensure(cob)
.then([](int) { throw std::runtime_error("ensure"); })
.ensure(cob);
EXPECT_THROW(f.get(), std::runtime_error);
EXPECT_EQ(2, count);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment