user_actions テーブルにエディットが保存されない

ユーザーが他の人の投稿を編集するたびに、そのアクションが user_actions テーブルに記録されると考えていましたが、実際には sporadically(一部のユーザーの一部のケースでのみ)しか発生していないことに気づきました。

これは意図された動作でしょうか、それとも見落としている条件があるのでしょうか?

この問題を再現するための手順を詳しく説明するのは難しいですが、私がこの事実に気づいた方法は以下の通りです:

  1. 編集通知がある投稿を見つける:
  2. 指定された acting_user_id(編集者)、user_id(編集されたユーザー)、target_topic_id を用いて user_actions をクエリします。私の場合は以下の通りです:
select * from user_actions ua 
where ua.acting_user_id = 229 
and ua.user_id = 259 
and ua.target_topic_id = 1907;

結果は以下の通りです:

  • アクションタイプ 2 は、編集されたユーザーが編集者から「いいね」を受け取ったことを意味します。
  • アクションタイプ 6 は、編集者が編集されたユーザーに返信したことを意味します。
  id   | action_type | user_id | target_topic_id | target_post_id | target_user_id | acting_user_id |         created_at         |         updated_at
-------+-------------+---------+-----------------+----------------+----------------+----------------+----------------------------+----------------------------
 78476 |           2 |     259 |            1907 |          17893 |                |            229 | 2020-03-20 03:39:12.255619 | 2020-03-20 03:39:12.395574
 78478 |           6 |     259 |            1907 |          17900 |                |            229 | 2020-03-20 03:44:04.847102 | 2020-03-20 03:44:04.847102

UI でこれらのアクションを確認できますが、EDIT を示す action_type 11 も存在すると予想していました。

UI で編集を確認できるだけでなく、target_post_id を用いて post_revisions テーブルをクエリすることで、その存在も確認できます:

select id, user_id, post_id, number, created_at, updated_at from post_revisions pr where post_id = 17893;

  id  | user_id | post_id | number |         created_at         |         updated_at         |
------+---------+---------+--------+----------------------------+----------------------------+--------
 8927 |     229 |   17893 |      2 | 2020-03-20 03:40:06.644576 | 2020-03-20 03:43:32.769535 |

では、なぜこのアクションが user_actions に表示されないのでしょうか?

「いいね!」 1

編集はそこに保存されるものではありません。編集は post_revisions に保存されます。

「いいね!」 2

はい、編集そのものではなく、user_action の EDIT イベントのことです:

問題は、このイベントが 90% の場合に発火することです。なぜ残りの 10% では機能しないのかがわかりません。

「いいね!」 1

編集通知が作成されるケースを完全に理解していないのか、それとも私が考えているよりもはるかに広範な問題なのか、今気づきました。

主な仮定

ユーザー A がユーザー B が書いた内容を編集すると、以下のことが起こります。

  • post_revisions テーブルに新しい行が追加されます。
  • action_type = 11user_actions テーブルに新しい行が追加されます。
  • /u/userB/notifications/edits にアクセスすると、ユーザー B はユーザー A による新しい編集を確認できます(これは user_actions に依存します)。
  • 投稿の鉛筆アイコンをクリックすると、ユーザー B はユーザー A が行った実際の編集を確認できます(これは post_revisions に依存します)。

テスト

上記の仮定が正しい場合、このクエリはユーザー B(この場合は ID 259)が作成した投稿の post_revisions テーブル内のすべての行(自分自身またはシステムユーザーによる編集を除く)と、対応する action_type = 11user_actions の行を表示するはずです。

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 259 -- ユーザー ID を選択
)
select
  up.user_id as my_user_id,
  ua.user_id as target_user_id,
  pr.post_id,
  ua.target_post_id,
  pr.user_id as editor_user_id,
  ua.acting_user_id,
  ua.action_type,
  pr.created_at as edit_created_at,
  ua.created_at as action_created_at
from
  post_revisions pr
  inner join my_user_posts up on up.id = pr.post_id
  and up.user_id != pr.user_id -- 自己編集除外
  and pr.user_id != -1 -- システム編集除外
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- EDIT アクションのみ
order by
  pr.post_id,
  pr.created_at;

期待される出力

すべての行に post_revisions データと user_actions データの両方が含まれていること。

実際の出力

一部の post_revisions の行には対応する user_actions データがありません。そのため、ユーザーは各投稿の鉛筆アイコンをクリックしてリビジョンを確認できますが、複数の編集があったことについての通知は受け取っていません

試したこと

  • user_action データのない古い投稿に追加の編集を行う。結果: user_action データも表示されませんでした。
  • 偽のユーザーを作成し、user_action データのない投稿の編集前の内容をコピーして、それを用いて投稿を作成し、別のユーザーが行ったのと同じ編集を適用する。結果: user_action データは正しく表示されました。
  • ユーザーがアクティブな場合とオフラインの場合の両方で上記の手順を繰り返す。結果: 変化はありませんでした。
  • 編集の猶予期間を変更して上記の手順を繰り返す。結果: 変化はありませんでした。

結論

  • この問題は以下のものではないようです:

    • ユーザー固有のもの。実際にはほぼすべてのユーザーで発生します。
    • 接続固有のもの。ユーザーがアクティブかオフラインかの違いは出力に影響しません。
    • 時間固有のもの。編集の猶予期間を変更しても効果はありませんでした。
  • この問題は以下のもののように見えます:

    • アクション固有のもの。他のアクション(LIKE、WAS_LIKED、RESPONSE、REPLY、MENTION、QUOTE)の通知には問題は見当たりません。問題があるのは EDIT アクションのみです。
    • 投稿固有のもの。すべての投稿で発生するわけではなく、特定の投稿(一見ランダムに)で発生します。
  • 可能性として、特定の投稿の作成時に EDIT user_actions の保存を妨げる何かが起こっているかもしれませんが、それが何なのかはわかりません。

  • また、これは設計上のものであり、特定の条件下ではユーザーが編集の通知を受け取らないようになっている可能性もありますが、そのようなドキュメントはどこにも見当たりません。

次のステップ

  • 編集通知が編集のたびにトリガーされない理由をご存知の場合は、お知らせください。
  • ご自身で Discourse インスタンスをお持ちの場合は、上記の SQL クエリをいくつかのユーザー ID で実行し、user_actions データの欠落が確認できるかどうかを確認し、結果をご報告いただけますでしょうか?
「いいね!」 1

編集猶予期間について、別のユーザーが投稿を編集する場合でも適用されることを、100% 明確に理解いただけているか確認したいだけです。

(はい、ユーザー A がユーザー B の投稿を編集する場合は、常に強制編集リビジョンが発生します。しかし、ユーザー A がユーザー B の投稿を 60 秒間に 6 回編集しても、6 つのリビジョンと 6 つの通知が作成されるわけではありません。上記のスクリーンショットをご覧いただくとお分かりの通り、リビジョンと通知はそれぞれ 1 つのみ作成されます。)

これらの編集は、すべて 5 分以上の間隔 で行われていますか?

「いいね!」 2

コメントありがとうございます、Jeff。確かに、これらの編集は5分以上間隔を空けて行われています。しかし、たとえそうではなかったとしても、単一の post_revision が作成される限り、必ずそれに伴う EDIT user_action も存在するはずです。

余談ですが、編集の猶予期間を0に変更してみましたが、その場合、すべての変更に対して2つの同一の post_revision が作成されます。これは仕様によるものなのか、それとも無関係なバグなのかはわかりません。

念のため確認しておきます。確認できて良かったです。

「いいね!」 1

どなたか、ご自身のDiscourseサイトで上記のクエリを実行し、type 11 の user_actions に対応する post_revisions が存在しないかどうかを確認していただけませんか?

コードを調査したところ、user_action タイプ 11 が取得されるのは、他人の投稿を編集した場合、または編集に関する通知を何らかの方法でトリガーした場合のみであると思われます。

「いいね!」 3

サン、ありがとう。私が期待していたのはそれでしたが、(少なくとも私のサイトでは)実際にはそうではありませんでした。私のクエリの結果からわかるように、場合によっては、ユーザーAがユーザーBの投稿を編集すると(post_revisionsに行が追加されます)、user_actionsに(action_type 11を持つ)対応する行が存在しないことがあります。これが私には理解できません。

その問題の再現手順はありますか?それとも一度きりの現象ですか?

「いいね!」 1

私のサイトを開始して以来、この現象は継続的かつ断続的に発生しています。上記で述べた通り、パターンを特定できていません。

データダンプを提供する方法があれば、あるいは他の情報が必要な場合は、喜んでお手伝いいたします。

念のため確認しますが、ここで報告されている実際のバグは以下の通りですか?

特定の条件下で、ユーザーAがユーザーBの投稿を編集しても、ユーザーBに通知されないこと?

「いいね!」 1

その通りです。通知はここにもユーザーボックスにも表示されません(どちらも user_actions に依存するため):

ただし、投稿の右上には表示されます(これは post_revisions に依存するため):

これをテストするためのクエリを作成しました。あなたのサイト(異なるユーザー ID で)で実行すれば、同様にギャップが確認できるはずです。

「いいね!」 1

これは当社がホストするインスタンスですか、それともセルフホストされたインスタンスですか?

当社の通知はここで発火します:

条件は非常に厳格です:

通知はここで作成されます:

これを妨げる可能性があるのは、

  1. Sidekiq がジョブで詰まっている、または一時停止されている場合

  2. 通知の途中でジョブを終了するという極めて稀な条件です

「いいね!」 2

私から、あなたがホストしているインスタンスでの具体的な例を挙げることができます。

この投稿(ID 1067)は、ユーザー 3 によって 2019 年 8 月 3 日 19:22 UTC に作成され、作成から数分後に私(ユーザー 2)によって編集されました。

しかし、その日そのユーザーが投稿 1001 と 1003 で受けた他の 2 つの編集とは異なり、タイプ 11 の user_action は作成されませんでした。

このクエリを実行すると、より明確に確認できます。

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 3 -- ユーザー ID を選択
)
select
  up.user_id as my_user_id,
  ua.user_id as target_user_id,
  pr.post_id,
  ua.target_post_id,
  pr.user_id as editor_user_id,
  ua.acting_user_id,
  ua.action_type,
  pr.created_at as edit_created_at,
  ua.created_at as action_created_at
from
  post_revisions pr
  inner join my_user_posts up on up.id = pr.post_id
  and up.user_id != pr.user_id -- 自己編集を除外
  and pr.user_id != -1 -- システム編集を除外
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- 編集アクションのみ
WHERE
  pr.created_at between '2019-08-03' and '2019-08-04'
order by
  pr.post_id,
  pr.created_at

いくつかの数値を確認したところ、日付によって、自己編集ではない post_revisions の 7% から 25% が対応する user_action を持っていないことがわかりました。

どうやらここにもバグがあるかもしれませんね、@Nacho_Caballero さん。少々お待ちください。粘り強く調査していただき、ありがとうございます。

「いいね!」 3

以下のバグがありました:

そして、この機能で実装を改善しました:

あるユーザーが別のユーザーの投稿に「いいね」をし、その後その投稿を編集した場合、編集時の通知が行われなかったというエッジケースがありました。

さらに、同じ編集者が 1 日以内に再度編集した場合でも、1 日に 1 回は必ず通知が行われるようにする安全対策を追加しました(同じ編集者からの重複編集通知は 1 日間抑制されます)。現時点ではこの設定は変更できません。

「いいね!」 6

素晴らしい。とても納得がいきます。修正していただき、ありがとうございます!

「いいね!」 1