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でポーリングして実行の様子をリアルタイムに確認して、終わったら画像がポン!みたいなのが多分できそう。