FacebookはC++11に丈夫で強力なFolly Futuresライブラリをもたらしました

2406 ワード

英語原版:https://www.infoq.com/news/2015/07/facebook-folly-futures
http://www.infoq.com/cn/news/2015/07/facebook-folly-futures/
Futureは同時動作を同期するためのコンポーネントであり、非同期動作の結果に対する読取り専用エージェントオブジェクトと見なすことができ、このオブジェクトの初期値は未知である.Futureのクライアントが操作が完了する前に値を読み込もうとすると、
ブロックされる可能性があります.Futureは通常、Futureの値への書き込みアクセスを提供するPromiseに関連付けられています.
非同期操作では、ブロックせずに読み取り専用のFutureをすぐに返すことができます.コードクリップの例は次のとおりです.
#include 
using folly::Future;
Future asyncOperation(Input);
Future f = asyncOperation(input);

ここのasyncOperationは非同期呼び出しのパッケージです.Futureのクライアントは、isReady()メソッドで関連するPromiseが完了したかどうかを確認し、value()メソッドで結果を取得できます.
Futureは関連付けられたPromiseによって作成され、非同期操作が完了するとsetValue()またはsetWith()メソッドで結果を設定できます.
using folly::Promise;
Future getEnergy(int year) {
  auto promise = make_shared>();
  std::thread([=]{
    promise->setWith(std::bind(getEnergySync, year));
  }).detach();
  return promise->getFuture();
}

Folly Futuresライブラリの本当の強みは、チェーンコールバックを容易に行い、コールバック地獄(callback hell)に入ることを避けることができるFuture::thenメソッドです.コールバックチェーンは、次のように表すことができます.
Future futureA(Output);
Future futureB(OutputA);
Future futureC(OutputB);
OutputD d(OutputC) {
  if (somethingExceptional) throw anException;
  return OutputD();
}
Future fut =
  fooFuture(input)
  .then(futureA)
  .then(futureB)
  .then(futureC)
  .then(d)
  .then([](OutputD outputD) { //     lambda   
    return outputD * M_PI;
  });

Folly Futuresライブラリが提供するもう一つの強力な構築ブロックは、集合内のすべてのFuturesが完了したときに完了するFutures集合を1つのFuturesと見なすことができる集合方法です.
 
集合メソッドと同様に、Folly Futuresライブラリでは、次の方法が提供されます.
  • collectAny:コレクションのいずれかのFutureが完了すると完了します.
  • collectN:N個のFutureが完成するまで待つ.
  • map:パラメータはFuture集合と1つの関数であり、集合パラメータ内の各Futureに対して関数パラメータのthen()メソッドを呼び出す.戻り値は新しいFuture配列です.
  • reduce:パラメータはFuture集合と2つのパラメータを持つ関数(reduceの値とreduceシーケンスの次の値)であり、集合パラメータの各Futureに対して関数パラメータが順次呼び出される.
    最後に、Folly Futuresは、コンテキストを実行することによってコールバックの実行を制御することもサポートします.たとえば、thenメソッドにエフェクタオブジェクトを入力し、今回のコールバックがこのエフェクタによって実行されるべきであることを指定できます.
    struct Executor {
      using Func = std::function;
      virtual void add(Func) = 0;
    };
    a(input).then(executor, b);

    詳細については、Folly Futureのドキュメントを参照してください.