Project

General

Profile

致命的 #753

WeakStorageのキーが削除されない

Added by Osamu Koga over 4 years ago. Updated about 1 year ago.

Status:
終了
Priority:
高め
Assignee:
Target version:
Start date:
2015-03-01
Due date:
% Done:

0%

プラグイン名:

Description

Ruby2.1.0以降でWeakStorageからキーが削除されなくなっており、以下のようなフロー(一例)で、プロフィール画面のツイートが表示されないなどの問題が発生しています。

  1. UserStream経由でユーザAのMessageが取得され、Home TLに流れてくる。
  2. Home TLの表示可能数がいっぱいになったため、MessageがHome TLから削除され、GCされる。
  3. 削除されたMessageと同じobject_idをもつ、別のオブジェクトが生成される(object_idはオブジェクトのアドレスとほぼ同じものなので、このような状況は頻繁に発生します)。
  4. ユーザAのプロフィールを表示しようとする。
  5. ユーザAの最新ツイートを元に、Message.new_ifnecessaryによってMessageが取得される。
  6. (キーが削除されていないので)WeakStorage#[]で対応するオブジェクトを取得しようとする。
  7. 実際には3.で違うオブジェクトが入っているので、type_strictに引っかかる。
  8. 例外が投げられ、ユーザTLは取得できなかったことになる。

Ruby2.1.0からファイナライザがシグナル割り込みと同じコンテキストで実行されるようになったため、finalizerの中でMonitorを使ったロックができなくなった(ロックしようとすると例外が投げられる・finalizer内の例外は握りつぶされる)ことが原因だと思われます。
参考: https://gist.github.com/osak/71648a7360d9a0a34f57

Rubyの実装を追いきれてないですが、Hash#delete_ifはI/Oじゃないので、途中でWeakStorage#[]とかに割り込まれて変なことになる恐れはない気がするので、とりあえずfinalizer中でのロックを外して様子を見てみます。


バックトレース

ɛ ʘɞʘ ɜ

Associated revisions

Revision b7c70f38 (diff)
Added by Osamu Koga over 4 years ago

Ruby2.1.0以降を使っていると、WeakStorageのキーが無効のまま削除されないことがあった。 refs #753

History

#1

Updated by toshi_a 初音 over 4 years ago

Ruby1.8の時にWeakStorage周りに不具合があって、ここで間違った値が返ってくると問題の特定が困難なのでそのへんでチェックしていたんだと思います。
Ruby2.1の仕様については全く知りませんでした。ただ、数週間とか起動しているんだけど、その問題に引っかかったことはないですね。とはいえ問題が起こる環境はどうやらあるらしいので、そのまま進めてください。

#2

Updated by Osamu Koga over 4 years ago

delete_ifの最中にWeakStorage#[]=が呼ばれ、やっぱりエラーになる事案が発生しました。やはり割り込まれないなんてうまい話はなかった……。
ファイナライザ内で新しくスレッドを作ればロック掛けられるのかな?

#3

Updated by toshi_a 初音 over 4 years ago

  • Status changed from 新規 to 実装待ち
  • Assignee set to Osamu Koga

こちらの認識だとエラーが発生する確率は減ってそうなんですが、実際どうなんでしょう。今日からリハビリ開始なので検証はできてません。
クラッシュする頻度が上がっていないのであれば、一旦この段階で出してしまっていいと思います

finalizerのコンテキストだとオブジェクト自身への参照はないので、SerialThreadとかに投げてやったうえでロックをかけるとうまくいくかもしれませんね。前にも書いたとおりこちらでは一度も再現できていないので、そちらで試してもらえますか。

#4

Updated by toshi_a 初音 about 1 year ago

  • Status changed from 実装待ち to 終了
  • バックトレース updated (diff)

数年間、このようなクラッシュ報告はなかったためcloseします。
同様の問題が発生したら新たにチケットを作ってください。

Also available in: Atom PDF