BT

堅牢で強力なFeatureをC++11で実現するFacebook Folly Feature

| 作者: Sergio De Simone フォローする 17 人のフォロワー , 翻訳者 吉田 英人 フォローする 0 人のフォロワー 投稿日 2015年8月11日. 推定読書時間: 4 分 |

原文(投稿日:2015/07/13)へのリンク

Facebookは先頃,Folly Futureという,既存のstd::futureを機能拡張するC++11ライブラリを導入した

Futureは並列操作の同期に使用される構成要素である。最初は値の分からない非同期演算の結果を参照する,読み取り専用のプロキシオブジェクトがFutureだ。まだ完了(fulfill)していないFutureの値をクライアントが読み出そうとすると,そのクライアントはブロックされる。ひとつのFutureは通常,ひとつのPromiseに関連付けられている。Futureの値への書き込みアクセスを提供するのがPromiseだ。

以下のコードで示すような非同期操作では,ブロックされることなく,読み取り専用のFutureをすぐに返すことが可能だ。

#include <folly/futures/Future.h> 
using folly::Future;

Future<Output> asyncOperation(Input);
Future<Output> f = asyncOperation(input);

asyncOperationは非同期呼び出しのラッパである。 クライアントは次にFutureにアクセスして,関連するPromiseisReady()メソッドを使って完了しているかチェックした上で,value()を使ってその値を取得する。

Futureはその関連するPromiseから生成されて,setValue()setWith()のいずれかを使って値を設定することができる。

using folly::Promise;

Future<double> getEnergy(int year) {
  auto promise = make_shared<Promise<double>>();

  std::thread([=]{
    promise->setWith(std::bind(getEnergySync, year));
  }).detach();
  
  return promise->getFuture();
}

Folly Futuresが本領を発揮するのはFuture::thenメソッドを使うときだ。コールバックの連鎖が簡単に実現可能であるため,コールバック地獄を防止できる。チェーンがどのように動作するのかを以下に示す。

Future<OutputA> futureA(Output);
Future<OutputB> futureB(OutputA);
Future<OutputC> futureC(OutputB);

OutputD d(OutputC) {
  if (somethingExceptional) throw anException;
  return OutputD();
}

Future<double> fut =
  fooFuture(input)
  .then(futureA)
  .then(futureB)
  .then(futureC)
  .then(d)
  .then([](OutputD outputD) { // lambdas are ok too
    return outputD * M_PI;
  });

Folly Futuresの提供する,もうひとつの強力なビルディングブロックがcollectメソッドだ。Futureのコレクションを,すべてのFutureの完了によって完了状態になる単一のFutureとして扱うことができる。collertと同じように,次の機能も提供されている。

  • collectAny: 入力のFutureのいずれかの完了によって完了する。
  • collectN: N個のFutureが完了するまで待機する。
  • map: Futureのコレクションと関数を設定し,各入力Futureのthen()に対してその関数をコールする。Futureの別の配列を返す。
  • reduce: Futureのコレクション以外に2つの引数関数(換算値と換算シーケンスの次の値)を取って,それぞれのFutureにその関数を適用する。

最後に,Folly Futuresでは,コールバックの実行時に実行コンテキストの概念もサポートされている。executorオブジェクトをthenに渡して,そのコールバックをexecutor経由で行うようなことも可能だ。

struct Executor {
  using Func = std::function<void()>;
  virtual void add(Func) = 0;
};

a(input).then(executor, b);

Folly Futureの詳しい情報は,資料で見ることができる。

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

誤植 by kom low

タイトルの"Feature"は原文では"Future"です。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

1 ディスカッション

InfoQにログインし新機能を利用する


パスワードを忘れた方はこちらへ

Follow

お気に入りのトピックや著者をフォローする

業界やサイト内で一番重要な見出しを閲覧する

Like

より多いシグナル、より少ないノイズ

お気に入りのトピックと著者を選択して自分のフィードを作る

Notifications

最新情報をすぐ手に入れるようにしよう

通知設定をして、お気に入りコンテンツを見逃さないようにしよう!

BT