RのGearman Worker改修した(Perlだけど)

個人メモエントリ。R で Gearman Worker(というか今考えると R じゃなくても system 関数的に何でも呼べる Worker)をデモ用に仕立てるために、色々と機能追加した。

Perl R 間のやり取り

前はバッククオートで R を起動して、R からの STDOUT を Perl でログに吐くだけだったけど、もうちょっと工夫して Perl と R で色々とやり取りできるようにした。

  • CMD |openして、buffering を無くして R の STDOUT を逐次獲得

    • my $oldfh = select IN; $| = 1; select $oldfh; ←bufferfing 無くす方法。知らんかった。
  • STDOUT に特定のプレフィックスがあったら Perl の関数を呼び出せる

    • R ではできない・やりにくい様な処理を Perl で代わりに実行するイメージ

    • 終わるまで R では待っていて欲しいので、R 側で名前付きパイプを blocking モードで開く

      • readLines(fifo(args$fifo, open = 'read', blocking = TRUE), n=1)n=1は微妙かも

ここに無駄に苦労した。名前付きパイプとか正直よく知らなかったけど、大した通信じゃなければ気を付けずに使っても大丈夫そうだ。

Rworker::Download/Upload

で、STDOUT 使ってキックできる関数としてファイルのダウンロード・アップロードができる関数を準備。

  • Rworker::Download

    • URL を渡すと Furl を使って tempfile にダウンロードして、ファイル名を返してくれる。
  • Rworker::Upload

    • URL とキーとファイル名を渡すと、Furl を使って POST を叩いてくれる。

これで RCurl を使わずともファイルを HTTP/HTTPS でやり取りできる。fifo を使って処理が終わるまで待ってくれる。画像作った場合、最後にそれをアップロードとかできる。これくらいなら R でやれよって話ですが。

そもそも R スクリプト自体を HTTP/HTTPS で取得

色々(例えば worker と web のサーバが分かれるとか)考えていると、R スクリプト自体をどこにおくべきか迷ってきて、web のデータとして持つのが良さそうなんだけど、バージョン管理とか面倒だし。

というわけで、めんどくさいので R スクリプトは gist.github.com からダウンロードして実行する様なイメージで作ってみた。これも tempfile にダウンロードして、あとは普通に R に渡すだけ。今はリビジョン入りのパスで落としてるけど、多分なんとかすればいつも最新リビジョンを落とすとかできるはず。ジョブとして登録する意味では、リビジョン入りの方が何度実行しても同じ結果になるのでいいかも。

あとは web を作るだけ><

これでデモ用の web をなんとか作れそう。分析用のデータもアップロードインタフェース作るのめんどくさいので、gist から引っ張ってくる。というわけで、R とデータのパスを渡してジョブを DB に登録して、Gearman::Client を実行して、ajax でポーリングして実行の様子をリアルタイムに確認して、終わったら画像がポン!みたいなのが多分できそう。