用户操作表中未存储编辑内容

我原以为每次用户编辑他人的帖子时,该操作都会被记录在 user_actions 表中,但我刚刚意识到这种情况只是偶尔发生(仅针对某些用户在某些时候)。

这是预期的行为吗?还是我忽略了某些条件?

很难提供逐步复现此问题的步骤,但我发现该问题的过程如下:

  1. 找到带有编辑通知的帖子:
  2. 针对给定的 acting_user_id(编辑者)、user_id(被编辑者)和 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 中确认这两项操作,但我也期望能找到表示编辑操作的操作类型 11。

除了在 UI 中看到编辑记录外,我还可以通过查询 post_revisions 表并指定 target_post_id 来确认编辑的存在:

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 个赞

Edits are not meant to be stored there, they are stored in post_revisions.

2 个赞

Right, not the edit. I mean the user_action EDIT event:

The thing is that it’s triggered 90% of the time. I don’t understand why it doesn’t work the other 10%

1 个赞

I just realized that either I don’t fully understand the cases where an edit notification is created or this is a much more widespread problem than I thought.

Main assumptions

If User A edits what User B wrote, several things happen:

  • A new row gets added to the post_revisions table.
  • A new row gets added to the user_actions table with action_type = 11.
  • By going to /u/userB/notifications/edits, User B will be able to see that a new edit was made by User A (this depends on user_actions).
  • By clicking on the pencil icon in his post, User B will be able to see the actual edit that User A performed (this depends on post_revisions).

Test

If the above assumptions are correct, this query should show all the rows in the post_revisions table for posts created by User B (in this case, id 259) that were edited by any user (other than himself, or the system user), along with the corresponding rows in user_actions for action_type = 11.

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 259 -- choose a user 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 -- no self edits
  and pr.user_id != -1 -- no system edits
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- only EDIT actions
order by
  pr.post_id,
  pr.created_at;

Expected output

Every row has both post_revisions data along with user_actions data.

Actual output

Some of the post_revisions rows doesn’t have matching user_actions data. Therefore, the user can see the revisions by clicking on the pencil in each post, but wasn’t notified about receiving several edits.

Things I’ve tried

  • Adding an additional edit to an old post without user_action data. Result: the user_action data also did not appear.
  • Creating a fake user, copying the pre-edit content of a post without user_action data, creating a post with it and applying the same edit that was done with a different user. Result: the user_action data appeared correctly.
  • Repeating the above procedures when the user is active or offline. Result: no change.
  • Repeating the above procedures changing the editing grace period. Result: no change.

Conclusions

  • The issue doesn’t appear to be:

    • user-specific. It happens to practically every user.
    • connection-specific. The fact that the user is active or offline doesn’t change the output.
    • time-specific. Changing the editing grace period had no effect.
  • The issue appears to be

    • action-specific. I have not seen any issues notifying any of the other actions (LIKE, WAS_LIKED, RESPONSE, REPLY, MENTION or QUOTE). The only problem is with EDIT actions.

    • post-specific. It doesn’t happen to every post, only specific ones (seemingly at random)

  • One possibility is that something is happening during the creation of specific posts to prevent EDIT user_actions from being saved, but I have no idea what this could be.

  • It’s also possible that this is happening by design and that there are specific conditions under which users are not notified of edits, but I haven’t seen this documented anywhere.

Next steps

  • If you know a reason why edit notifications might not get triggered every time there is an edit, please let me know.
  • If you have your own Discourse instance, could you run the above SQL query on some of your user ids to see if you also see missing user_actions data and report back?
1 个赞

I just want to be 100% sure you’re clear about edit grace periods, which would still apply even if there is a different user editing the post.

(Yes, if user A edits user B’s post, there is always a forced edit revision, but that doesn’t mean that if user A edits user B’s post 6 times in 60 seconds, there are 6 revisions and 6 notifications created. There will be only one revision and one notification, as you can see in the above screenshot.)

Are each of these edits more than 5 minutes apart?

2 个赞

Jeff,感谢你的评论。我可以确认,是的,这些编辑之间的间隔确实超过了 5 分钟。但即使不是这样,只要创建了一个 post_revision,难道不应该始终伴随一个 EDIT user_action 吗?

顺便提一下,我还尝试将编辑宽限期改为 0,结果发现每次更改都会创建两个完全相同的 post_revision。我不确定这是设计如此,还是另一个无关的 bug。

只是想确认一下,确认一下很好。

1 个赞

是否有人能在自己的 Discourse 站点上运行上述查询,看看是否也会出现没有对应类型为 11 的 user_actions 的 post_revisions?

仔细查看我们的代码后,我认为只有在编辑他人的帖子或通过其他方式触发与该编辑相关的通知时,才会获得 user_action 类型为 11 的记录。

3 个赞

谢谢,Sam。这正是我所预期的,但实际情况并非如此(至少在我的网站上是这样)。正如我的查询结果所示,在某些情况下,用户 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-08-03 19:22 UTC 创建,几分钟后被我(用户 2)编辑。

然而,并没有创建类型为 11 的 user_action(与该用户当天在帖子 1001 和 1003 上收到的其他 2 次编辑不同)

如果您运行以下查询,可以更清楚地看到这一点:

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

我进行了一些统计,根据不同日期,7% 到 25% 的非自编辑 post_revisions 没有对应的 user_action。

看来我们这里确实有个 bug @Nacho_Caballero,请稍等。感谢你的坚持。

3 个赞

我们曾遇到以下问题:

随后,我通过以下功能改进了实现:

此前存在一个边界情况:当用户点赞了另一位用户的帖子,随后又编辑该帖子时,系统不会就编辑操作发出通知。

此外,我还添加了一项安全机制,确保即使是由同一编辑者重复编辑,每天至少无条件通知一次(同一编辑者的重复编辑通知会在 1 天内被抑制)。目前该机制尚不可配置。

6 个赞

太好了,这很有道理。非常感谢你的修复!

1 个赞