3

Heroku が推奨するように、delayed_job と foreman を使用して最近バックグラウンド タスクに移動した新しいアクティブ レコード レコードを作成するタスクがあります。

これで問題なく動作することもありますが、ブラウザーの Rails アプリが応答しなくなることがあります。

この時点で、遅延したすべてのジョブが完了し、すべての新しいレコードが作成されたことをデータベースから確認できます。

ただし、プロセスを強制終了すると、さらに 11,200 行の端末出力が得られます。これは主に、モデルに対する 2 つのメソッドの Web プロセスによる実行で構成され、どちらもデータベースへの呼び出しを伴います。

validate :hit_database_to_see_if_model_exists?

before_save :get_rows_from_database_and_perform_calculation  

プロセスを強制終了する前後でレコード数が変わらないため、すでにデータベースにヒットしていると思われる INSERT ステートメントもいくつかあります。

これが私のProfileです:

web: bundle exec rails server thin -p $PORT -e $RACK_ENV

worker: bundle exec rake jobs:work

そのため、「スタック オーバーフロー」(ウープ) が発生しているように感じます。あなたは何か光を当てることができますか:

  • 一般的に何が起こっているのですか?
  • Rails でこの「スタック オーバーフロー」が発生している場所
  • 「Ctrl + C」を押した後にこれらのことが実際に起こっているのか、それともその時点で端末に出力されているだけなのか?
  • 何が原因でしょうか?
  • どうすればデバッグ/修正できますか?

アップデート

バックグラウンド タスクによって Web プロセスに割り当てられている特定のタスクがあるようですが、ブラウザが「起動」されるまで実行されません。状況によってはすべて実行されますが、数が多すぎるとアプリが失敗します。これを引き起こしている可能性のあるものについて何か考えはありますか?

アップデート

2 つの別々のウィンドウで Web プロセスとワーカー プロセスを実行してみました。

このシナリオでは、ブラウザーがハングする問題を再現できず、いずれの場合もワーカー プロセスは正常に完了しました。

ただし、ブラウザーに触れないと、Web ウィンドウに出力が表示されないという興味深い観察結果が得られました。ただし、ブラウザーに触れると、その時点でワーカー プロセスが行っていることの何千行もが Web ウィンドウに表示されます。

これは正常ですか?これにより、問題が何であるかが明らかになりますか?

アップデート

プロセスを強制終了した後の端末出力の下部に、「Kill​​ed: 9」と表示されます

07:45:21 システム | すべてのプロセスに SIGKILL を送信する

殺された: 9

この 9 は正確には何を指していますか? これは異常ですか?

アップデート

私は使っている:

  • 遅延ジョブ 3.0.4
  • 遅延ジョブ_アクティブ_レコード 0.3.3
  • 遅延した_ジョブ_ウェブ 1.1.2
  • 職長 0.60.2

解像度

以下の@Justinの回答(およびこの関連する質問)に感謝します。Ruby はデフォルトで stdout をバッファリングし、このバッファがオーバーフローしてアプリが応答しなくなったようです。$stdout.sync = trueconfig/environments/development.rb の先頭に追加したところ、問題は解決したようです。

4

1 に答える 1

3

これは部分的な答えにすぎませんが、デバッグに役立つ場合があります。

Railsはデフォルトでロギングをバッファリングし、Webリクエストごとにそれをフラッシュします。1つのオプションは、ロガーをより単純なロガーに置き換えることです。

Rails.logger = Logger.new(STDOUT)

より頻繁にフラッシュするようにバッファリングされたロガーを構成することもできます

Rails.logger.auto_flushing = (Rails.env.development? || Rails.env.test?)

STDOUTにも注意する必要があります。現在のプロジェクトでは、バックグラウンドブートとバックグラウンドブートの両方でstdoutフラッシュを有効にしconfig.ruています(sidekiqを使用しているため、ブートプロセスが少し異なる場合があります)

STDOUT.sync = true

あなたのより大きな問題に関しては、

Railsプロセスがバックグラウンドタスクを実行していることに驚いています。少なくとも実験のために、それを無効にするオプションはありますか?

次に、標準のデバッグツールがあります。saveでのすべてのデータベース呼び出しは心配なので、それらを無効にするさまざまな組み合わせを試して、何かが改善されるかどうかを確認します。特にそのうちの2つでは、たとえば、before_saveフックがモデルの値を変更すると、検証がトリガーされる可能性があります。それがbefore_saveフックをリセットする場合、ループが発生します。

于 2013-01-16T22:34:40.263 に答える