Edições não estão sendo salvas na tabela user_actions

Eu achava que, toda vez que um usuário edita o post de outra pessoa, essa ação seria registrada na tabela user_actions, mas acabei percebendo que isso só acontece esporadicamente (apenas para alguns usuários, em alguns momentos).

Isso é o comportamento esperado ou há outra condição que não estou considerando?

É difícil fornecer um passo a passo para reproduzir esse problema, mas foi assim que detectei:

  1. Encontre um post com uma notificação de edição:
  2. Faça uma consulta na tabela user_actions para o acting_user_id dado (o editor), o user_id dado (o editado) e o topic_id dado. No meu caso:
select * from user_actions ua 
where ua.acting_user_id = 229 
and ua.user_id = 259 
and ua.target_topic_id = 1907;

Isso é o que obtenho:

  • O tipo de ação 2 significa que o usuário editado recebeu um LIKE do editor.
  • O tipo de ação 6 significa que o editor respondeu ao usuário editado.
  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

Posso confirmar ambas essas ações na interface, mas também esperaria encontrar um action_type 11 indicando a EDIÇÃO.

Além de ver a edição na interface, também posso confirmar sua existência na tabela post_revisions consultando usando o 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 |

Então, por que essa ação não aparece em user_actions?

Edições não devem ser armazenadas lá; elas são armazenadas em post_revisions.

Certo, não a edição. Quero dizer o evento user_action EDIT:

O problema é que ele é acionado 90% das vezes. Não entendo por que não funciona nos outros 10%.

Acabei de perceber que ou não entendo totalmente os casos em que uma notificação de edição é criada, ou este é um problema muito mais generalizado do que eu pensava.

Principais suposições

Se o Usuário A edita algo escrito pelo Usuário B, várias coisas acontecem:

  • Uma nova linha é adicionada à tabela post_revisions.
  • Uma nova linha é adicionada à tabela user_actions com action_type = 11.
  • Ao acessar /u/userB/notifications/edits, o Usuário B poderá ver que uma nova edição foi feita pelo Usuário A (isso depende de user_actions).
  • Ao clicar no ícone de lápis em sua postagem, o Usuário B poderá ver a edição real realizada pelo Usuário A (isso depende de post_revisions).

Teste

Se as suposições acima estiverem corretas, esta consulta deve mostrar todas as linhas da tabela post_revisions para postagens criadas pelo Usuário B (neste caso, id 259) que foram editadas por qualquer usuário (exceto ele mesmo ou o usuário do sistema), juntamente com as linhas correspondentes em user_actions para action_type = 11.

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 259 -- escolha um id de usuário
)
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 -- sem autoedições
  and pr.user_id != -1 -- sem edições do sistema
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- apenas ações de EDIÇÃO
order by
  pr.post_id,
  pr.created_at;

Saída esperada

Cada linha deve conter dados tanto de post_revisions quanto de user_actions.

Saída real

Algumas linhas de post_revisions não possuem dados correspondentes em user_actions. Portanto, o usuário pode ver as revisões clicando no lápis em cada postagem, mas não foi notificado sobre várias edições recebidas.

Coisas que tentei

  • Adicionar uma edição adicional a uma postagem antiga sem dados de user_action. Resultado: os dados de user_action também não apareceram.
  • Criar um usuário fictício, copiar o conteúdo pré-edição de uma postagem sem dados de user_action, criar uma postagem com ele e aplicar a mesma edição que foi feita com outro usuário. Resultado: os dados de user_action apareceram corretamente.
  • Repetir os procedimentos acima quando o usuário está ativo ou offline. Resultado: nenhuma mudança.
  • Repetir os procedimentos acima alterando o período de graça para edições. Resultado: nenhuma mudança.

Conclusões

  • O problema não parece ser:

    • específico do usuário. Acontece com praticamente todos os usuários.
    • específico da conexão. O fato de o usuário estar ativo ou offline não altera a saída.
    • específico do tempo. Alterar o período de graça para edições não teve efeito.
  • O problema parece ser:

    • específico da ação. Não observei nenhum problema ao notificar nenhuma das outras ações (LIKE, WAS_LIKED, RESPONSE, REPLY, MENTION ou QUOTE). O único problema é com ações de EDIÇÃO.

    • específico da postagem. Não acontece com todas as postagens, apenas com algumas específicas (parece ser aleatório).

  • Uma possibilidade é que algo esteja acontecendo durante a criação de postagens específicas que impede que as ações de usuário de EDIÇÃO sejam salvas, mas não tenho ideia do que poderia ser isso.

  • Também é possível que isso esteja acontecendo por design e que existam condições específicas nas quais os usuários não são notificados sobre edições, mas não encontrei isso documentado em nenhum lugar.

Próximos passos

  • Se você souber de algum motivo pelo qual as notificações de edição podem não ser acionadas toda vez que há uma edição, por favor, me avise.
  • Se você tiver sua própria instância do Discourse, poderia executar a consulta SQL acima em alguns dos ids de usuário para ver se também observa dados ausentes de user_actions e me relatar?

Eu só quero ter 100% de certeza de que você está claro sobre os períodos de graça para edições, que ainda se aplicariam mesmo que um usuário diferente esteja editando a postagem.

(Sim, se o usuário A editar a postagem do usuário B, sempre haverá uma revisão de edição forçada, mas isso não significa que, se o usuário A editar a postagem do usuário B 6 vezes em 60 segundos, haverá 6 revisões e 6 notificações criadas. Haverá apenas uma revisão e uma notificação, como você pode ver na captura de tela acima.)

Cada uma dessas edições foi feita com mais de 5 minutos de intervalo?

Obrigado pelo comentário, Jeff. Posso confirmar que, sim, essas edições estão com mais de 5 minutos de diferença. Mas mesmo que não estivessem, desde que seja criada uma única post_revision, não deveria haver SEMPRE uma EDIT user_action correspondente?

Como observação lateral, também tentei alterar o período de tolerância para edição para 0 e, ao fazer isso, são criadas 2 post_revisions idênticas para cada alteração. Não sei se isso é intencional ou se é um bug não relacionado.

Só confirmando isso, bom ter certeza.

Alguém poderia executar a consulta acima em seu site Discourse para ver se também obtém post_revisions sem user_actions correspondentes do tipo 11?

Analisando nosso código, acredito que você só recebe o tipo de user_action 11 se editar a postagem de outra pessoa ou disparar uma notificação sobre a edição de alguma outra forma.

Obrigado, Sam. Era isso que eu esperava, mas não é o que eu encontrei (no meu site, pelo menos). Como você pode ver nos resultados da minha consulta, em alguns casos, o usuário A edita uma postagem do usuário B (o que adiciona uma linha em post_revisions), mas não há uma linha correspondente em user_actions (com action_type 11). Isso é o que eu não entendo.

Você tem uma reprodução do problema? É algo que ocorreu apenas uma vez?

Isso vem acontecendo de forma contínua e esporádica desde que iniciei meu site. Como mencionei acima, não consegui identificar um padrão.

Se houver uma maneira de eu fornecer um dump de dados ou se precisar de outras informações, ficarei feliz em ajudar.

Apenas para garantir que estou entendendo corretamente, o bug real que você está relatando aqui é:

Em algumas condições, o Usuário A edita uma postagem do Usuário B e o Usuário B não recebe nenhuma notificação?

Exatamente. A notificação não aparece aqui nem na caixa do usuário (já que ambas dependem de user_actions):

No entanto, ela aparece no canto superior direito da postagem (já que isso depende de post_revisions):

Escrevi uma consulta para testar isso. Se você executá-la no seu site (com diferentes IDs de usuário), também deverá ver lacunas.

Esta é uma instância hospedada por nós ou uma instância auto-hospedada?

Nossa notificação é acionada aqui:

A condição é bastante rigorosa:

A notificação é criada aqui:

O que poderia quebrar isso é:

  1. O Sidekiq com fila de jobs acumulada ou pausado

  2. Condição extremamente rara de interromper o job no meio do processo de notificação

Posso dar um exemplo específico em uma instância hospedada por você.

Esta postagem (id 1067), criada pelo usuário 3 em 2019-08-03 19:22 UTC, recebeu uma edição minha (usuário 2) alguns minutos após sua criação.

No entanto, nenhuma user_action do tipo 11 foi criada (diferentemente das outras 2 edições que esse usuário recebeu naquele dia nas postagens 1001 e 1003)

Você pode ver mais claramente se executar esta consulta:

with my_user_posts as (
  select
    p.id,
    p.user_id
  from
    posts p
  where
    p.user_id = 3 -- escolha um 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 -- sem edições próprias
  and pr.user_id != -1 -- sem edições do sistema
  left join user_actions ua on ua.target_post_id = pr.post_id
  and ua.action_type = 11 -- apenas ações de EDIT  
WHERE
  pr.created_at between '2019-08-03' and '2019-08-04'
order by
  pr.post_id,
  pr.created_at

Executei algumas análises e, dependendo da data, entre 7% e 25% das post_revisions que não são edições próprias não possuem uma user_action correspondente.

Pode ser que, afinal, tenhamos um bug aqui, @Nacho_Caballero… fiquem atentos. Obrigado por persistir nisso.

Tivemos este bug:

E melhorei a implementação com esta funcionalidade:

Tivemos um caso limite em que, quando um usuário curtia uma postagem de outro usuário e, em seguida, a editava, não recebíamos notificação sobre a edição.

Além disso, adicionei uma proteção de segurança que garante que notifiquemos incondicionalmente uma vez por dia, mesmo que seja o mesmo editor. (Suprimimos notificações de edições repetidas do mesmo editor por 1 dia). Isso não é configurável no momento.

Excelente. Isso faz muito sentido. Muito obrigado pela correção!