Memento memo.

Today I Learned.

Concurrent Rubyで並行処理プログラミング

Rubyで並行処理を書きたかったのですが、自前でスレッドセーフなプログラムを書ける気がしないのでgemを探して来ました。

Concurrent Ruby

github.com

Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why

と書いてあるので、諸々の並行処理の実装があるみたいです。スレッドセーフらしいです。 READMEを読むとActorやらChannelやら書いてあります。

とりあえず今回は一番basicっぽいAsyncを使って並行でHTTPリクエストを投げる処理を実装してみます。

Async

Async: A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's gen_server.

らしいです。

とりあえずDocumentを読みつつコードを書いてみました。

1秒のレイテンシがあるmock serverに5回リクエストを投げる処理です。

通常の直列処理では5秒かかってる処理が、 Async使った並行処理では1秒で終わっています。

実装ポイント
  • Concurrent::Async をincludeする
  • initializerメソッドで super() をコールする
  • .async をメソッドチェインに挟んで非同期処理をdispatchする
  • .wait で処理の終了を待つ(ブロッキングなメソッド)
  • .value で結果を取り出す

まとめ

結構手軽に並行処理が書けて良さげです。

HTTPリクエストの並列化自体は Faraday + Typhoeus なんかでも簡単に書けるんですが、 Concurrent Rubyの方が汎用的ですね。

ActorとかChannelあたりはまだ触れてないので後日触ってみようと思います。

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

メタプログラミングRuby 第2版

メタプログラミングRuby 第2版