バグ #1476
未完了MastodonのFTLをデータソースとして使っているとたまにNoMethodErrorでクラッシュする
説明
MastodonのFTLを抽出タブのデータソースとして使っていると、たまにNoMethodErrorでクラッシュします。
RESTかストリーミングどちらが起因かは分かりません。そもそも、本当にFTLが原因かも分かりません。
例外が発生したタブの情報をダンプするコードを差し込んで確認した限りでは、私の環境ではFTLを購読しているタブのみがこのエラーを引いているという感じです。
バックトレース¶
Traceback (most recent call last): 3: from /home/shibafu/git/mikutter/vendor/bundle/ruby/2.7.0/gems/pluggaloid-1.5.0/lib/pluggaloid/stream.rb:80:in `block in each' 2: from /home/shibafu/git/mikutter/vendor/bundle/ruby/2.7.0/gems/pluggaloid-1.5.0/lib/pluggaloid/stream.rb:80:in `loop' 1: from /home/shibafu/git/mikutter/vendor/bundle/ruby/2.7.0/gems/pluggaloid-1.5.0/lib/pluggaloid/stream.rb:81:in `block (2 levels) in each' /home/shibafu/git/mikutter/plugin/extract/extract.rb:279:in `block (3 levels) in modify_extract_tabs': undefined method `retweet_source' for nil:NilClass (NoMethodError)
ファイル
Shibafu Midorino さんが約4年前に更新
TL;DR: wontfixでいいかもしれません。
collectionへの変更を通してmodify_extract_tabsに到達するルートを調べていたところ、mastodon_restには確かにnilを流す可能性がありました。
mastodon_rest.rb::query() で Plugin::Mastodon::Status.bulk_build の内容をそのまま全てcollectionに流しています。
ただ、このメソッドの戻り値がnilを含みうるのは Plugin::Mastodon::Status.merge_or_create() が nil を返した時だけです。
merge_or_create() が nil を返す可能性があるのは、@@mutes
に投稿者のacctが入っていた時だけです。
このクラス変数は、mikutter 4.1以降Mastodon Worldを追加した時、ミュート・ミュート解除のコマンドを呼び出した時を除いて書き込みされていません。
(mikutter 4.0まではこの変数は起動時(だったかな…)に更新されていました。)
ですが、私の環境にはこの変数を強制的に更新するプラグインがデバッグ用で入っていました。そのため、発生したと考えられます。
@@mutes
を使ったミュート処理がobsoleteなら、このチケットはクローズで良いと思います。
念の為、影響するプラグインを外した状態でもうしばらく様子は見てみます。
toshi_a 初音 さんが約4年前に更新
確かに、これはやめたほうがいいですね。 @@mutes
はミュート使わないので知りませんでした。
アカウントミュートのクライアントサイド処理¶
これは、merge_or_createでnilを返すのではなく、show_filterを通すとアカウントミュートされたアカウントの投稿を取り除けるようにすべきです。
show_filterは、Twitterプラグインのクライアントサイドミュートに使われていて、MiraclePainterや通知プラグインなど、アカウントミュートされた投稿を処理したくないプラグインで使います。
(アカウントミュートしたらそもそもサーバから配信されないというのは真ですが、それでいいなら現在のMastodonプラグインに @@mutes
なんてなかっただろうし……)
複数のMastodon Worldでアカウントミュートしたときの処理¶
今までの実装だと、複数のMastodon Worldを使っているとき、いずれかのWorldでアカウントミュートされているユーザの投稿は、全て削除されているようです。
ただ、連合タイムラインなどの抽出タブデータソースがサーバ直下とアカウント直下両方にあるのって、サーバサイドでアカウントミュートやブロックが反映されているか否かの違いでしたよね。
今はshow_filterで削除するより、予め切り落とされたデータソースを用意したほうが良いのかな。
対応方針¶
4.1¶
現状をなるべく変えず、変更を最小限に。クラッシュする可能性を排除することを優先。
- merge_or_createはnilを返さず、常にMessageを返す
- merge_or_createからミュート機能を切り離すのは、可能ならこのタイミングでやりたい
4.2以降¶
どんな仕様にするかを議論しなければならない。
候補↓
- ミュートした投稿はshow_filterを通したときに結果から削除される
- 抽出タブデータソースに演算子「〜がミュートしているアカウントが投稿者」を追加する
など