From 0f6e30432ea98c2ef4542499a8cfe6181d1ace24 Mon Sep 17 00:00:00 2001 From: Hans Fugal Date: Wed, 25 Feb 2015 09:54:53 -0800 Subject: [PATCH] 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 --- folly/futures/Future-inl.h | 10 ++++++++++ folly/futures/Future.h | 7 +++++++ folly/futures/test/FutureTest.cpp | 12 ++++++++++++ 3 files changed, 29 insertions(+) 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); +} -- 2.34.1