From: Hans Fugal Date: Wed, 25 Feb 2015 17:54:53 +0000 (-0800) Subject: Future::ensure X-Git-Tag: v0.27.0~15 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0f6e30432ea98c2ef4542499a8cfe6181d1ace24;p=folly.git 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 --- diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index c4eda605..a7183180 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -290,6 +290,16 @@ Future::onError(F&& func) { return f; } +template +template +Future Future::ensure(F func) { + MoveWrapper funcw(std::move(func)); + return this->then([funcw](Try&& t) { + (*funcw)(); + return makeFuture(std::move(t)); + }); +} + template template Future Future::onTimeout(Duration dur, F&& func, Timekeeper* tk) { diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 3459a7ad..a43755e1 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -342,6 +342,13 @@ class Future { Future>::type onError(F&& func); + /// func is like std::function 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 + Future ensure(F func); + /// Like onError, but for timeouts. example: /// /// Future f = makeFuture(42) diff --git a/folly/futures/test/FutureTest.cpp b/folly/futures/test/FutureTest.cpp index fabde15f..19dd1fa8 100644 --- a/folly/futures/test/FutureTest.cpp +++ b/folly/futures/test/FutureTest.cpp @@ -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); +}