S3に大きなファイルをアップロードした時、イベントが発火しない問題の原因と対策メモ


ファイル作成(PUT/POST)時にLambda FunctionをキックするイベントをセットしたS3のバケットがある。このバケットに対して、AWS SDK for Ruby 経由でサイズが大きなファイルをアップロードしたところ、イベントが発火しない問題があった。調査にそこそこ時間がかかったのでメモ。

まとめ

  • 原因は、ファイルアップロードの方式が「PUT」から「Multipart Upload」に変わったため。AWS SDK for Rubyのデフォルト設定ではファイルサイズが「15MB」以上になると、アップロード方式が自動的に切り替わる。
  • さらに、S3のイベント発火対象の操作に「Complete Multipart Upload」を選択していなかったため、アップロード方式が「Multipart Upload」になるとイベントが発火しなかった。
  • 対策は、イベント発火対象の操作に「Complete Multipart Upload」を追加で選択すればOK。

続きを読む →


RailsコンソールでRedisSessionStoreのセッションを取得し、中身を見る方法


また必要になりそうなのでメモ

  • redis-session-store
  • セッションIDはブラウザのCookieを見て事前に知っている想定


ActionMailerでメール送信方法を自作するためにコードを読んでみる


SendGridのWeb API v3 を使ってActionMailerでメール送信する gem を作成した時にActionMailer周りのコードを読んだのでメモ。

ちなみにActionMailerでSendGridを使う場合の公式の推奨は、SMTP APIを使う方法 と思われる。SMTP APIを使う際に気になる点として、ユーザーIDとパスワードを指定しないといけない点がある。一方、Web APIでは管理画面で発行したAPI keyを指定する。API keyは環境ごとに複数発行可能で、かつ権限をカスタマイズすることもできる。情報が漏洩した際の対応のしやすさはWeb APIの方が優っていると考え、採用したかった。

まとめ

  • #initialize, #settings, #deliver! の3つのメソッドを実装した自作メール送信クラスを作成
  • 自作クラスをRails起動時の設定か、ActionMailer::Baseを継承したクラスでセット
  • ヘッダーや本文がセットされた Mail::Message のインスタンスが #deliver! の引数に渡されるので、このインスタンスから必要な情報を集めてメール送信処理を実装すればOK

続きを読む →


Ruby用バックグラウンドジョブライブラリ「sidekiq」のコードを読んでみる(前半)


自分が担当するRailsアプリケーションでバックグラウンドジョブを動かす必要が出てきた。

Railsでバックグラウンドジョブといえば二大巨頭の ResqueSidekiq があると思っている。どちらかといえば最近採用されているイメージがあるSidekiqに関して、どんなコードになっているか主要な部分をチェックしておきたい。

今回は、Railsにsidekiqを組み込んでジョブを登録する部分まで。Sidekiqを直接使ってジョブを登録する方法と、ActiveJob経由で登録する方法の2つを比べて見る。

まとめ

  • Sidekiqを直接使用する場合、Redisのコネクションプールを用意しておき、それを使用して各Jobの情報をキューにpushしているだけ。ジョブの登録に関してはシンプルだった。
  • ActiveJob経由もバックエンドを抽象化している分、少しコードが複雑になっているが、やっていることはほとんど同じだった。あとコードが綺麗で読みやすい。
  • Redisに登録される情報は以下の通り。
    • 「queues」というSetにキューの名前を登録。
    • 「queue:default」というListにジョブの情報を追加。ジョブの情報はクラス(class)、ジョブの引数(args)、ID(jid)等。
    • ActiveJob経由の場合、クラスは ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper になっている。

続きを読む →


Ruby用API生成フレームワーク「grape」のコードを読んでみる (後半)


前回からの続きでRuby用のAPI生成フレームワーク grape のコードを読んで見たのでメモ。

前半は初期化処理を見た。今回は、リクエスト処理の部分を見ていく。

まとめ

  • マウントしたクラス => マウントしたクラスのシングルトンなインスタンス => Grape::Routerと呼び出していき、ここでリクエストに対応する Grape::Router::Routeインスタンスを検索する。その後、Grape::Router::Routeが内部で保持するGrape::Endpointのインスタンスに処理を委譲している。
  • リクエストに対応するRouteの検索は正規表現で一発、さらに名前付きのキャプチャを使用して高速化している。ここは、こういった方法があるのかと勉強になった。
  • 各Endpointは最初のリクエストが来た時に初期化処理を行うため、1回目のリクエストの処理は2回目以降に比べて少し時間がかかると思われる。
  • Grape::Endpointのインスタンスをリクエストごとにdupし #call! を実行する。
  • チェーンされている各種Middlewareを実行し、最終的に Grape::Endpoint#run に到達する。
  • Grape::Endpoint#run では各種callbackの実行しつつ、自身がAPIの処理として定義したブロックを実行し、Rackレスポンスとしての結果を返却する。
  • 前半に比べると読みやすい印象。

続きを読む →