プロジェクト

全般

プロフィール

致命的 #753

完了

WeakStorageのキーが削除されない

Osamu Koga さんが9年以上前に追加. 6年以上前に更新.

ステータス:
終了
優先度:
高め
担当者:
対象バージョン:
開始日:
2015-03-01
期日:
進捗率:

0%

プラグイン名:

説明

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中でのロックを外して様子を見てみます。


バックトレース

ɛ ʘɞʘ ɜ

他の形式にエクスポート: Atom PDF