ユーザーが他の人の投稿を編集するたびに、そのアクションが user_actions テーブルに記録されると考えていましたが、実際には sporadically(一部のユーザーの一部のケースでのみ)しか発生していないことに気づきました。
これは意図された動作でしょうか、それとも見落としている条件があるのでしょうか?
この問題を再現するための手順を詳しく説明するのは難しいですが、私がこの事実に気づいた方法は以下の通りです:
編集通知がある投稿を見つける:
指定された 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
sam
(Sam Saffron)
2020 年 3 月 24 日午前 4:14
4
編集はそこに保存されるものではありません。編集は post_revisions に保存されます。
「いいね!」 2
はい、編集そのものではなく、user_action の EDIT イベントのことです:
validates :action_type, presence: true
validates :user_id, presence: true
LIKE = 1
WAS_LIKED = 2
NEW_TOPIC = 4
REPLY = 5
RESPONSE = 6
MENTION = 7
QUOTE = 9
EDIT = 11
NEW_PRIVATE_MESSAGE = 12
GOT_PRIVATE_MESSAGE = 13
SOLVED = 15
ASSIGNED = 16
LINKED = 17
ORDER =
Hash[
*[
問題は、このイベントが 90% の場合に発火することです。なぜ残りの 10% では機能しないのかがわかりません。
「いいね!」 1
編集通知が作成されるケースを完全に理解していないのか、それとも私が考えているよりもはるかに広範な問題なのか、今気づきました。
主な仮定
ユーザー A がユーザー B が書いた内容を編集すると、以下のことが起こります。
post_revisions テーブルに新しい行が追加されます。
action_type = 11 で user_actions テーブルに新しい行が追加されます。
/u/userB/notifications/edits にアクセスすると、ユーザー B はユーザー A による新しい編集を確認できます(これは user_actions に依存します)。
投稿の鉛筆アイコンをクリックすると、ユーザー B はユーザー A が行った実際の編集を確認できます(これは post_revisions に依存します)。
テスト
上記の仮定が正しい場合、このクエリはユーザー B(この場合は ID 259)が作成した投稿の post_revisions テーブル内のすべての行(自分自身またはシステムユーザーによる編集を除く)と、対応する action_type = 11 の user_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 データは正しく表示されました。
ユーザーがアクティブな場合とオフラインの場合の両方で上記の手順を繰り返す。結果 : 変化はありませんでした。
編集の猶予期間を変更して上記の手順を繰り返す。結果 : 変化はありませんでした。
結論
次のステップ
編集通知が編集のたびにトリガーされない理由をご存知の場合は、お知らせください。
ご自身で 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 が作成されます。これは仕様によるものなのか、それとも無関係なバグなのかはわかりません。
Nacho_Caballero:
これらの編集は5分以上離れています
念のため確認しておきます。確認できて良かったです。
「いいね!」 1
Nacho_Caballero:
このクエリ
どなたか、ご自身のDiscourseサイトで上記のクエリを実行し、type 11 の user_actions に対応する post_revisions が存在しないかどうかを確認していただけませんか?
sam
(Sam Saffron)
2020 年 4 月 22 日午前 7:05
11
コードを調査したところ、user_action タイプ 11 が取得されるのは、他人の投稿を編集した場合、または編集に関する通知を何らかの方法でトリガーした場合のみであると思われます。
「いいね!」 3
サン、ありがとう。私が期待していたのはそれでしたが、(少なくとも私のサイトでは)実際にはそうではありませんでした。私のクエリの結果からわかるように、場合によっては、ユーザーAがユーザーBの投稿を編集すると(post_revisionsに行が追加されます)、user_actionsに(action_type 11を持つ)対応する行が存在しないことがあります。これが私には理解できません。
sam
(Sam Saffron)
2020 年 4 月 22 日午前 8:16
13
その問題の再現手順はありますか?それとも一度きりの現象ですか?
「いいね!」 1
私のサイトを開始して以来、この現象は継続的かつ断続的に発生しています。上記で述べた通り、パターンを特定できていません。
Nacho_Caballero:
試したこと
user_action データのない古い投稿に追加の編集を行う。結果 :user_action データも表示されませんでした。
偽のユーザーを作成し、user_action データのない投稿の編集前の内容をコピーして、それを用いて投稿を作成し、異なるユーザーで行ったのと同じ編集を適用する。結果 :user_action データが正常に表示されました。
ユーザーがアクティブな場合とオフラインの場合の両方で上記の手順を繰り返す。結果:変化はありませんでした。
編集の猶予期間を変更して上記の手順を繰り返す。結果:変化はありませんでした。
データダンプを提供する方法があれば、あるいは他の情報が必要な場合は、喜んでお手伝いいたします。
sam
(Sam Saffron)
2020 年 4 月 22 日午前 8:36
15
念のため確認しますが、ここで報告されている実際のバグは以下の通りですか?
特定の条件下で、ユーザーAがユーザーBの投稿を編集しても、ユーザーBに通知されないこと?
「いいね!」 1
その通りです。通知はここ にもユーザーボックスにも表示されません(どちらも user_actions に依存するため):
ただし、投稿の右上には表示されます(これは post_revisions に依存するため):
Nacho_Caballero:
テスト
これをテストするためのクエリを作成しました。あなたのサイト(異なるユーザー ID で)で実行すれば、同様にギャップが確認できるはずです。
「いいね!」 1
sam
(Sam Saffron)
2020 年 4 月 22 日午後 10:42
17
これは当社がホストするインスタンスですか、それともセルフホストされたインスタンスですか?
当社の通知はここで発火します:
if user_ids.present?
DB.after_commit do
Jobs.enqueue(:notify_post_revision,
user_ids: user_ids,
post_revision_id: post_revision.id
)
end
end
end
def self.after_post_unhide(post, flaggers)
条件は非常に厳格です:
通知はここで作成されます:
ActiveRecord::Base.transaction do
User.where(id: args[:user_ids]).find_each do |user|
next if post_revision.hidden && !user.staff?
PostActionNotifier.alerter.create_notification(
user,
Notification.types[:edited],
post_revision.post,
display_username: post_revision.user.username,
acting_user_id: post_revision&.user_id,
revision_number: post_revision.number
)
end
end
これを妨げる可能性があるのは、
Sidekiq がジョブで詰まっている、または一時停止されている場合
通知の途中でジョブを終了するという極めて稀な条件です
「いいね!」 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
sam
(Sam Saffron)
2020 年 5 月 4 日午前 7:58
22
以下のバグがありました:
committed 07:40AM - 04 May 20 UTC
Due to a refactor in e90f9e5cc47 we stopped notifying on edits if
a user liked a… post and then edited.
The like could have happened a long time ago so this gets extra
confusing.
This change makes the suppression more deliberate. We only want
to suppress quite/link/mention if the user already got a reply
notification.
We can expand this suppression if it is not enough.
そして、この機能で実装を改善しました:
committed 07:55AM - 04 May 20 UTC
This ensures that at a minimum you are notified once a day of
repeat edits by th… e same user.
Long term we may consider winding this down to say 1 hour or
making it configurable.
あるユーザーが別のユーザーの投稿に「いいね」をし、その後その投稿を編集した場合、編集時の通知が行われなかったというエッジケースがありました。
さらに、同じ編集者が 1 日以内に再度編集した場合でも、1 日に 1 回は必ず通知が行われるようにする安全対策を追加しました(同じ編集者からの重複編集通知は 1 日間抑制されます)。現時点ではこの設定は変更できません。
「いいね!」 6
素晴らしい。とても納得がいきます。修正していただき、ありがとうございます!
「いいね!」 1