From aa0467019981739bd34c63330d729875f61d853c Mon Sep 17 00:00:00 2001 From: James Sedgwick Date: Mon, 24 Oct 2016 10:29:14 -0700 Subject: [PATCH] sync README Summary: as above Reviewed By: yfeldblum Differential Revision: D4066250 fbshipit-source-id: 7dfe07656dd338ec42fcd966328e46331202bf58 --- folly/futures/README.md | 84 ++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/folly/futures/README.md b/folly/futures/README.md index d25649d5..a9d7d88e 100644 --- a/folly/futures/README.md +++ b/folly/futures/README.md @@ -8,29 +8,29 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac

Brief Synopsis #

-
#include <folly/futures/Future.h>
-using namespace folly;
-using namespace std;
+
#include <folly/futures/Future.h>
+using namespace folly;
+using namespace std;
 
-void foo(int x) {
+void foo(int x) {
   // do something with x
   cout << "foo(" << x << ")" << endl;
 }
 
 // ...
 
-  cout << "making Promise" << endl;
-  Promise<int> p;
-  Future<int> f = p.getFuture();
-  f.then(foo);
-  cout << "Future chain made" << endl;
+  cout << "making Promise" << endl;
+  Promise<int> p;
+  Future<int> f = p.getFuture();
+  f.then(foo);
+  cout << "Future chain made" << endl;
 
 // ... now perhaps in another event callback
 
-  cout << "fulfilling Promise" << endl;
-  p.setValue(42);
-  cout << "Promise fulfilled" << endl;
-
+
cout << "fulfilling Promise" << endl; + p.setValue(42); + cout << "Promise fulfilled" << endl; +

This would print:

@@ -445,7 +445,7 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
WARNING: Chaining together multiple calls to onError will NOT necessarily behave in the same way as multiple catch {} blocks after a try. Namely, if you throw an exception in one call to onError, the next onError will catch it.
-
intGeneratorThatMaybeThrows() // returns Future<int>
+
intGenerator() // returns a Future<int>, which might contain an exception
   // This is a good opportunity to use the plain value (no Try)
   // variant of then()
   .then([](int i) { 
@@ -749,103 +749,103 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
 
 

Future<T>::within() returns a new Future that will complete with the provided exception (by default, a TimedOut exception) if it does not complete within the specified duration. For example:

-
using std::chrono::milliseconds;
-Future<int> foo();
+
using std::chrono::milliseconds;
+Future<int> foo();
 
 // f will complete with a TimedOut exception if the Future returned by foo()
 // does not complete within 500 ms
-f = foo().within(milliseconds(500));
+f = foo().within(milliseconds(500));
 
 // Same deal, but a timeout will trigger the provided exception instead
-f2 = foo().within(milliseconds(500), std::runtime_error("you took too long!"));
-
+
f2 = foo().within(milliseconds(500), std::runtime_error("you took too long!")); +

onTimeout() #

Future<T>::onTimeout() lets you simultaneously set up a timeout and a timeout handler. For example:

-
Future<int> foo();
-foo()
+
Future<int> foo();
+foo()
   .onTimeout(milliseconds(500), []{
     // You must maintain the resultant future's type
     // ... handle timeout ...
     return -1;
-  })
+  })
   .then(...);
-
+

The astute reader might notice that this is effectively syntactic sugar for

-
foo()
+
foo()
   .within(milliseconds(500))
   .onError([](const TimedOut& e) {
     // handle timeout
     return -1;
-  })
+  })
   .then(...);
-
+

get() and wait() with timeouts #

get() and wait(), which are detailed in the Testing article, optionally take timeouts:

-
Future<int> foo();
+
Future<int> foo();
 // Will throw TimedOut if the Future doesn't complete within one second of
 // the get() call
-int result = foo().get(milliseconds(1000));
+int result = foo().get(milliseconds(1000));
 
 // If the Future doesn't complete within one second, f will remain
 // incomplete. That is, if a timeout occurs, it's as if wait() was
 // never called.
-Future<int> f = foo().wait(milliseconds(1000));
-
+
Future<int> f = foo().wait(milliseconds(1000)); +

delayed() #

Future<T>::delayed() returns a new Future whose completion is delayed for at least the specified duration. For example:

-
makeFuture()
+
makeFuture()
   .delayed(milliseconds(1000))
   .then([]{
     // This will be executed when the original Future has completed or when
     // 1000ms has elapsed, whichever comes last.
   });
-
+

futures::sleep() #

sleep() returns a Future<Unit> that will complete after the specified duration. For example:

-
futures::sleep(milliseconds(1000)).then([]{
+
futures::sleep(milliseconds(1000)).then([]{
   // This will be executed after 1000ms
 });
-

Interrupts and Cancellations

Interrupts are a mechanism for Future holders to send a signal to Promise holders. Here's how to use them.

Let's say that your Futures code kicks off some long, expensive operation in another thread. A short while later, something comes up that obviates the need for the result of that operation. Are those resources gone forever? Not necessarily. Enter interrupts.

+

Interrupts and Cancellations

Interrupts are a mechanism for Future holders to send a signal to Promise holders. Here's how to use them.

Let's say that your Futures code kicks off some long, expensive operation in another thread. A short while later, something comes up that obviates the need for the result of that operation. Are those resources gone forever? Not necessarily. Enter interrupts.

Interrupts allow Future holders to send signals in the form of exceptions to Promise holders, who are free to handle the interrupt as they please (or not at all). For example:

-
auto p = std::make_shared<Promise<int>>();
-p->setInterruptHandler([p](const exception_wrapper& e){
+
auto p = std::make_shared<Promise<int>>();
+p->setInterruptHandler([p](const exception_wrapper& e){
   // Handle the interrupt. For instance, we could just fulfill the Promise
   // with the given exception:
   p->setException(e);
   
   // Or maybe we want the Future to complete with some special value
-  p->setValue(42);
+  p->setValue(42);
 
   // Or maybe we don't want to do anything at all! Including not setting
   // this handler in the first place.
-});
+});
 
-auto f = p->getFuture();
+auto f = p->getFuture();
 // The Future holder can now send an interrupt whenever it wants via raise().
 // If the interrupt beats out the fulfillment of the Promise *and* there is
 // an interrupt handler set on the Promise, that handler will be called with
 // the provided exception
-f.raise(std::runtime_error("Something went awry! Abort!"));
+f.raise(std::runtime_error("Something went awry! Abort!"));
 
 // cancel() is syntactic sugar for raise(FutureCancellation())
-f.cancel();
-
+
f.cancel(); +

Going forward, we'd like to integrate interrupts with major Future interface provides as a way to cancel RPCs and the like, but that's not in place yet. This is a bleeding edge feature—please let us know your use cases so that we can iterate!

Testing

Testing futures-based code does not have to be a pain. Here are some tips and idiomatic approaches.

Extracting values synchronously #

-- 2.34.1