バグ #1345
未完了mastodonプラグインのプロフィールタブを開いたときにトゥート単位で取得APIが呼ばれる
説明
mastodonプラグインでプロフィールタブに開いたときにトゥートの取得をapi/v1/statuses/<id>の単位で取得する場合があるようです。
以下は自分のプロフィールタブを開いたときの出力です。
notice: {MIKUTTER_DIR}/core/plugin/mastodon/api.rb:181:in `send_request': Mastodon::API.call get https://social.mikutter.hachune.net/api/v1/accounts/3/statuses [["Authorization", "Bearer bef25405f1a5f17098fea5f9d737996a309b12dd4a476e16566ef9debf719a2e"]] [] notice: {MIKUTTER_DIR}/core/plugin/mastodon/api.rb:181:in `send_request': Mastodon::API.call get https://social.mikutter.hachune.net/api/v1/statuses/102238914714412414 [] [] notice: {MIKUTTER_DIR}/core/plugin/mastodon/api.rb:181:in `send_request': Mastodon::API.call get https://social.mikutter.hachune.net/api/v1/statuses/102238611243190984 [] [] notice: {MIKUTTER_DIR}/core/plugin/mastodon/api.rb:181:in `send_request': Mastodon::API.call get https://social.mikutter.hachune.net/api/v1/statuses/102238611242850330 [] [] notice: {MIKUTTER_DIR}/core/plugin/mastodon/api.rb:181:in `send_request': Mastodon::API.call get https://social.mikutter.hachune.net/api/v1/statuses/102238511354097739 [] []
常にTLに読み込まれていない(フォロイーのふぁぼ・BTなどで出てきたフォローしていない)ようなユーザーでは取得件数が多くなるような印象があります。
Pawooユーザーのような画像投稿が多い場合に読み込みが多くなっている気もします。
API仕様もわかっていないのでアレですが、トゥート単位よりはある程度まとめて取れるとサーバーに優しそうではあります。
cob odo さんが5年以上前に更新
worldonにおいてこのような実装にした背景を説明します。
人数の少ないMastodonサーバーにおいて、WebUIで外部サーバーのユーザーの詳細を開くとよくわかるんですが、使用しているサーバーに到達していないメッセージが全く表示されず、場合によっては1つか2つくらいしかメッセージがない状態になってしまいます。これはまさに「サーバーに優しい」実装をMastodonが選択したからだろうと思います。
では本当にそのユーザーの最新メッセージをすべて取りたいと思ったらどうしたらいいのかというと、そのユーザーが属しているサーバーの https://docs.joinmastodon.org/api/rest/accounts/#get-api-v1-accounts-id-statuses を叩けばいいです。しかし、このAPIは認証が必須なので、そのサーバーにアカウントが必要ですし、もちろん(複数のActivityPub実装の中で)そのサーバーがMastodonである必要があります。
そこで、ActivityPubのAPIを使います。ActivityPubには認証なしで対象ユーザーの最新メッセージ一覧を取得するAPIがあります。
しかし取得したActivityPub形式のメッセージをMastodonのものに変換するAPIといったものは存在しません。ということは自前で変換する必要が出てくるわけですが、特に(比較的最近追加されたアンケートなど)Mastodonの拡張がActivityPub上でどのように表現されるのかを考慮すると、新機能が登場するたびに対応し続けるのは作業量的に厳しくなってしまいます。
そこで、認証の要らない単独 Status
の取得APIを使います。これによって、対象のサーバーのバージョンが対応する限りにおいて、自然に変換してくれるわけです。
まとめると、
- ActivityPubのAPIでメッセージ一覧を取得
- 取得したメッセージ一覧からURIのみを抽出
- 各URIを単独
Status
取得APIでリクエストしてStatus
形式に変換してもらう
……という手順を踏んでいます。従って、この挙動は意図通りです。
その上での軽減策ですが、対象ユーザーのドメインが、登録済みmastodon worldのいずれかのドメインと一致すれば、そのサーバーで通常のAPIを叩く、というのはまず実装したほうがいいでしょう。
それ以外の状況では、全取得を諦めるか、ActivityPubメッセージから Mastodon Status
への変換処理を気合でサポートし続けるかの二択になると思います。
toshi_a 初音 さんが5年以上前に更新
なるほど。個人的には、1ノードが数十件リクエストするだけなので、URLをトゥートするよりはサーバの負荷は低いので別にいいかな、と思ってました。
しかし、全般的に言えることですが、同時接続数の制御を今のところ行っていないので、これはやったほうが良いと思います。Twitterの時は16本まで同時にコネクションを張れるようにしていました。
メモ: 具体的には SerialThreadGroup
にThread poolのような機能がある