2013年5月23日木曜日

railsでの簡易遅延実行

※この記事の内容は、あくまで遅延実行を実装するための方法であり、マルチスレッドやバックグラウンドプロセスとは異なります。よって、herokuなどの30秒timeoutの壁はこの方法では破れません。諦めてdelayed_jobやcarrierwave_backgrounderを利用してください。

お久しぶりです ヾ(o・ω・)ノ

最近時間がないせいか記事がなくて寂しいので書いてみようと思います。
また、iOSネタしかなかったので、たまにはrailsネタで。

以下のソースコードで遅延実行が実装できます。

# Gemfile
gem "rack_after_reply"


# app/controllers/hogehoges_controller.rb
def hogemethod
  env["rack_after_reply.callbacks"] << lambda {
    # 時間のかかる処理
      
  }
  # 202 Accepted を返す
  format.html { render status: :accepted }
end

これだけ。

いやー、簡単ですねー。

仕組み的には代表的な Rack サーバー(Mongrel, Passenger, Thin, Unicorn, WEBrick )が各リクエストを処理するメソッドをフックして、コールバックを実行しているとのこと。

herokuはリクエストのタイムアウトが30秒に制限されているのでいくら遅延実行しても無理でしたが、AmazonEC2経由でS3に大容量ファイルをアップロードする機能はこれで実装出来ました。
(まあアップロードにcarrierwaveを使っているので最終的にcarrierwave_backgrounderに変更しましたが。)
サーバー側のプロセス的には結局アップロードが完了するまで掴みっぱなしなのであまり意味はないですが、使い方次第では簡単にユーザビリティを上げられるのでオススメです。
何よりロジックを変えなくていいのが良い!

ただしまあ問題もありまして。
エラーハンドリングが困難なのが一番の問題ですねえ (・ω・ ;)(; ・ω・)
上記のファイルアップロードなどの場合、先にレスポンスが返ってしまうので、画面上は正常にアップロードされたと表示されているにも関わらずサーバー側でコケている的なことが起こり得ます (´・ω・`)

なので、遅延実行に入る前に、可能な限りデータチェックはしておきましょう。

ではでは。

0 件のコメント:

コメントを投稿