Make a SharedPromise from a Future
authorPhil Willoughby <philwill@fb.com>
Mon, 26 Sep 2016 11:59:05 +0000 (04:59 -0700)
committerFacebook Github Bot 1 <facebook-github-bot-1-bot@fb.com>
Mon, 26 Sep 2016 12:08:44 +0000 (05:08 -0700)
Summary: Makes it easy to split a Future into multiple Futures

Reviewed By: rongrong

Differential Revision: D3885897

fbshipit-source-id: 6ac9fb22444dd828fbdebb44b06bf3d93d0f7583

folly/futures/SharedPromise-inl.h
folly/futures/SharedPromise.h
folly/futures/test/SharedPromiseTest.cpp

index 90d0dd3d3758de9a45247813922268aad9869835..490e08644f18a608e385f23fc1cc4746d2375cd5 100644 (file)
@@ -47,6 +47,11 @@ SharedPromise<T>& SharedPromise<T>::operator=(
   return *this;
 }
 
+template <class T>
+SharedPromise<T>::SharedPromise(Future<T> future) {
+  future.then(&SharedPromise<T>::setTry, this);
+}
+
 template <class T>
 size_t SharedPromise<T>::size() {
   std::lock_guard<std::mutex> g(mutex_);
index cdc284ddbe4f96f1ef99fc714cd261cc359c83af..d1f8a94961621f442f9ec0b58e3ec4b2b5c2e153 100644 (file)
@@ -46,6 +46,13 @@ public:
   SharedPromise(SharedPromise<T>&&) noexcept;
   SharedPromise& operator=(SharedPromise<T>&&) noexcept;
 
+  /**
+   * Provide a way to split a Future<T>. Note that while the Futures from
+   * `getFuture()' depend on the completion of the parameter Future they do not
+   * inherit any other properties such as Executor's passed to `via' etc.
+   */
+  explicit SharedPromise(Future<T>);
+
   /**
    * Return a Future tied to the shared core state. Unlike Promise::getFuture,
    * this can be called an unlimited number of times per SharedPromise.
index 36b5169b5bbd3b1ed66de6fb36ac02af60e7496b..b7245cc04ac5fd478f68fa80b01eebd69ed69b1f 100644 (file)
@@ -125,3 +125,33 @@ TEST(SharedPromise, interruptHandler) {
   f.cancel();
   EXPECT_TRUE(flag);
 }
+
+TEST(SharedPromise, splitFutureSuccess) {
+  Promise<int> p;
+  SharedPromise<int> sp(p.getFuture());
+  auto f1 = sp.getFuture();
+  EXPECT_FALSE(f1.isReady());
+  p.setValue(1);
+  EXPECT_TRUE(f1.isReady());
+  EXPECT_TRUE(f1.hasValue());
+  auto f2 = sp.getFuture();
+  EXPECT_TRUE(f2.isReady());
+  EXPECT_TRUE(f2.hasValue());
+}
+
+TEST(SharedPromise, splitFutureFailure) {
+  Promise<int> p;
+  SharedPromise<int> sp(p.getFuture());
+  auto f1 = sp.getFuture();
+  EXPECT_FALSE(f1.isReady());
+  try {
+    throw std::runtime_error("Oops");
+  } catch (...) {
+    p.setException(exception_wrapper(std::current_exception()));
+  }
+  EXPECT_TRUE(f1.isReady());
+  EXPECT_TRUE(f1.hasException());
+  auto f2 = sp.getFuture();
+  EXPECT_TRUE(f2.isReady());
+  EXPECT_TRUE(f2.hasException());
+}