Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exibir (e retornar via API) a quantidade de qualificações positivas e negativas do conteúdo #1607

Merged
merged 2 commits into from
Feb 18, 2024

Conversation

Rafatcb
Copy link
Collaborator

@Rafatcb Rafatcb commented Jan 21, 2024

Mudanças realizadas

Backend

Agora, duas novas propriedades são retornadas junto do conteúdo: tabcoins_credit e tabcoins_debit. Em consultas que retornavam tabcoins de um conteúdo, essas novas propriedades também são retornadas (exemplo: ao qualificar um conteúdo).

Endpoints afetados:

  • GET /api/v1/contents
  • POST /api/v1/contents
  • GET /api/v1/contents/[username]
  • GET /api/v1/contents/[username]/[slug]
  • PATCH /api/v1/contents/[username]/[slug]
  • GET /api/v1/contents/[username]/[slug]/children
  • GET /api/v1/contents/[username]/[slug]/parent
  • GET /api/v1/contents/[username]/[slug]/root
  • POST /api/v1/contents/tabcoins

Frontend

A apresentação na UI é feita por meio de um Tooltip, tanto na lista de conteúdos quanto na página do conteúdo, para a publicação e para os comentários.

Lista de conteúdos Conteúdo
Página da lista de conteúdos Página do conteúdo

Resolve #1370

Tipo de mudança

  • Nova funcionalidade

Checklist:

  • As modificações não geram novos logs de erro ou aviso (warning).
  • Eu adicionei testes que provam que a correção ou novo recurso funciona conforme esperado.
  • Tanto os novos testes quanto os antigos estão passando localmente.

@Rafatcb Rafatcb added front Envolve modificações no frontend back Envolve modificações no backend novo recurso Nova funcionalidade/recurso labels Jan 21, 2024
Copy link

vercel bot commented Jan 21, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
tabnews ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 18, 2024 4:58pm

@Rafatcb Rafatcb force-pushed the return-content-tabcoins-credits-and-debits branch from 18e3661 to fa9d54c Compare January 28, 2024 01:28
@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Jan 28, 2024

  • 95c53d7: mudança na implementação da função get_current_balance_credit_debit para considerar como total_credit e total_debit apenas eventos do tipo update:content:tabcoins, para desconsiderar ganhos provenientes da criação do conteúdo (create:content:text_child e create:content:text_root).
  • b434a45: retorno ao buscar um conteúdo específico (GET /contents/[username]/[slug], GET /contents/[username]/[slug]/parent e GET /contents/[username]/[slug]/root) com teste específico. Defini se deve retornar com base no values.limit === 1, se ter uma sugestão melhor, pode falar.
  • e5daeb6: retorno ao buscar uma árvore de conteúdos (GET /contents/[username]/[slug]/children e também na UI via getStaticProps)
  • fa9d54c: retorno ao votar num conteúdo (POST /contents/[username]/[slug]/tabcoins).

Eu modifiquei alguns testes para adicionar o orchestrator.createRate. O lado positivo disso é que um teste específico realmente só teria isso de diferença. O lado negativo é que se o teste for removido, não fica claro que isso estava sendo testado. Para mitigar o ponto negativo, renomeei o nome do teste em questão. Acham melhor criar um novo teste específico nos arquivos para testar esses valores de tabcoins_credit e tabcoins_debit?

Não implementei a UI pois ainda não teve um consenso dentre as opções oferecidas no issue #1370, mas essa é a "parte fácil" do PR.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 4, 2024

Realizei um stash com rebase, a única alteração foi no arquivo TabCoinButtons, onde implementei a UI para exibir a contagem em uma Tooltip, conforme comentei no issue (#1370 (comment)).

Editei o PR para atualizar os resultados do EXPLAIN ANALYZE. Também estou tirando de draft, já que não houve mais nenhum comentário.

PS: Está quebrado em homologação, imagino que por causa da migração que não foi executada.

Copy link
Collaborator

@aprendendofelipe aprendendofelipe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Faz sentido mandarmos tabcoins_debit como um valor <= 0 ou deveria ser um valor positivo (>= 0)?

Acho um pouco estranho retornar o valor negativo já que possui débito no nome, mas parece que facilitou a implementação, então não vejo problemas.

  1. Usei o EXPLAIN ANALYZE e a função get_current_balance_credit_debit trouxe um custo (aparentemente) relevante nas queries. Pode ser algo específico do EXPLAIN ANALYZE, que na prática não faça diferença. Precisa avaliar o tempo de execução com mais dados (homologação/produção). Enxergam alguma melhoria para as queries alteradas?

Precisamos pensar em como melhorar isso. Talvez até mudar algo na modelagem.

Uma opção para "contornar" esse custo seria calcular os votos sob demanda, realizando uma requisição separada. Na UI atual, essa requisição seria disparada ao realizar o hover nos votos.

Principalmente por ser custoso, precisa ter cache, e como seria um cache diferente dos dados da página estática, ficaria inconsistente com muita frequência.

  • b434a45: retorno ao buscar um conteúdo específico (GET /contents/[username]/[slug], GET /contents/[username]/[slug]/parent e GET /contents/[username]/[slug]/root) com teste específico. Defini se deve retornar com base no values.limit === 1, se ter uma sugestão melhor, pode falar.

Se conseguirmos melhorar o desempenho, acho que compensaria sempre retornar o crédito e débito e mostrar isso também na lista de conteúdos.

Acham melhor criar um novo teste específico nos arquivos para testar esses valores de tabcoins_credit e tabcoins_debit?

Acho que compensa um teste específico.

Está quebrado em homologação, imagino que por causa da migração que não foi executada.

Quando estiver tudo definido, vamos precisar quebrar o PR em dois, e a migration fica no primeiro PR. Assim não quebra nada, principalmente em produção.

@@ -120,7 +120,13 @@ async function findAll(values = {}, options = {}) {
contents.path,
users.username as owner_username,
content_window.total_rows,
get_current_balance('content:tabcoin', contents.id) as tabcoins,
${
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Será que não compensa retornar os créditos e débitos mesmo quando está devolvendo a lista de conteúdos?

O Tooltip com a mesma informação pode aparecer na lista de conteúdos e no conteúdo em si.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu havia removido tanto pela questão do custo maior quanto pela falta de espaço para exibir essa informação. Um Tooltip resolveria o segundo ponto.

Se descobrirmos como resolver o primeiro, podemos devolver também nas listas de conteúdos.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 6, 2024

Precisamos pensar em como melhorar isso. Talvez até mudar algo na modelagem.

Enquanto eu avaliava o issue #1370 (relacionado à este PR), eu acabei olhando o #1388, tanto que fiz esse comentário #1388 (comment) com alguns achados sobre o cache de TabCoins. Pensei que conseguiria retornar o tabcoins_credit e tabcoins_debit sem impacto de performance, o que não se mostrou verdade.

Eu ainda não consigo ter certeza sobre o impacto de desempenho apenas com o EXPLAIN ANALYZE. Vou estudar algumas alternativas para a implementação e criar um script para popular o banco de forma que eu consiga ver uma diferença de tempo real entre as queries. Quando eu ter um resultado sobre isso, comento aqui.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 10, 2024

Alterações no código

Atualizei os testes para criar um teste novo específico sobre o comportamento adicionado (o retorno de tabcoins_credit e tabcoins_debit) e fiz o rebase.

Análise de desempenho

Criei um banco com 227 mil usuários, 48 mil conteúdos e 114 mil votos (542 mil registros em balance_operations).

Para analisar os endpoints, executei cada query 5 vezes consecutivas diretamente no banco de dados (pelo pgAdmin4) e anotei os tempos. Isso não é nada "científico", mas dá a base de comparação necessária para entendermos quais queries precisam de atenção. Ordenei os tempos na tabela de resultados do melhor tempo de cada para o pior de cada.

Também disponibilizei o Explain de cada query em um site que possibiltia a visualização e compartilhamento do resultado. Caso alguém tenha problema em acessar os links futuramente, eu salvei no Wayback Machine, então é só pesquisar por lá.

GET /api/v1/contents/[username]/[slug]

get_current_balance get_current_balance_credit_debit Diferença (%)
51ms 233ms +356%
53ms 236ms +345%
73ms 242ms +231%
73ms 249ms +241%
83ms 269ms +224%

Explain: get_current_balance e get_current_balance_credit_debit.

Essa query precisa de melhorias.

⚠️ GET /api/v1/contents/[username]/[slug]/children

Primeiro eu realizei um teste com 27 comentários na publicação raiz em diferentes níveis (cenário "ok"), mas não teve impacto significativo:

get_current_balance get_current_balance_credit_debit Diferença (%)
59ms 62ms +5%
66ms 65ms -1%
73ms 78ms +7%
74ms 78ms +5%
119ms 88ms -26%

Explain com 27 comentários na publicação: get_current_balance e get_current_balance_credit_debit.

Então, decidi fazer o mesmo teste com 2027 comentários na publicação raiz em diferentes níveis (cenário extremo):

get_current_balance get_current_balance_credit_debit Diferença (%)
171ms 297ms +73%
188ms 298ms +58%
208ms 310ms +49%
212ms 312ms +47%
220ms 314ms +43%

Explain com 2027 comentários na publicação: get_current_balance e get_current_balance_credit_debit.

Interessante notar que o gargalo destas queries muda conforme a quantidade de comentários.

As publicações com mais comentários do TabNews provavelmente são Quem deseja acesso ao Repositório Privado do TabNews? (FECHADO) (804 comentários) e Tentando construir um pedaço de internet mais massa (747 comentários).

POST /contents/[user]/[slug]/tabcoins

get_current_balance get_current_balance_credit_debit Diferença (%)
49ms 45ms -8%
52ms 48ms -8%
53ms 49ms -8%
56ms 64ms +14%
77ms 79ms +3%

Explain: get_current_balance e get_current_balance_credit_debit.

A alteração dessa query não causou um impacto significativo.

Resumo / Conclusão

  • GET /api/v1/contents/[username]/[slug] precisa de melhorias tanto porque o impacto no desempenho foi significativo quanto porque é a query mais usada dentre as três.

  • GET /api/v1/contents/[username]/[slug]/children pode receber melhorias. Com poucos comentários, não há impacto. Com muitos (centenas ou milhares, coisa que hoje provavelmente temos em menos de 5 publicações) o impacto é mais significativo.

    Uma das publicações com muitos comentários está referenciada em vários lugares, que é a Tentando construir um pedaço de internet mais massa, então provavelmente é acessada algumas vezes por dia, o que faz com que essa query também mereça atenção, mas não é tão urgente/impactante quanto a anterior.

  • POST /contents/[user]/[slug]/tabcoins não precisa de melhorias.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 11, 2024

Melhorias

ROWS 1

Avaliando o visualizador do Explain, consegui mais informações sobre o que poderia melhorar. O primeiro ponto que decidi avaliar foi o "Bad estimation for number of rows", do Function scan. O Postgres estava estimando 1000 linhas, mas na verdade a função retorna sempre uma única linha. De acordo com a documentação, 1000 é o padrão, e eu poderia informar que retorno apenas 1. Informações complementares nessa resposta do Stack Overflow.

STABLE

Além disso, percebi que a função era criada como VOLATILE (padrão do node-pg-migrate). Pela documentação, vi que poderíamos usar STABLE. Esta categoria permite que o otimizador do Postgres otimize múltiplas chamadas da função para uma única chamada.

Porém, não funcionou. Nas consultas de POST /contents/[user]/[slug]/tabcoins não retornava mais o valor atualizado. Tentei modificar a query, mas não obtive sucesso com a função STABLE.

Resultados

Realizei a mesma metodologia do meu último comentário, no mesmo banco de dados.

GET /api/v1/contents/[username]/[slug]

get_current_balance get_current_balance_credit_debit Diferença (%)
50ms 49ms -2%
53ms 56ms +6%
53ms 56ms +6%
56ms 56ms =
63ms 80ms +27%

Explain: get_current_balance e get_current_balance_credit_debit.

O ROWS 1 trouxe uma ótima melhoria 🎉 . Para ter certeza que está "excelente" seria necessário ainda mais registros, para que as queries demorassem mais, dando uma noção maior da diferença do tempo de execução.

⚠️ GET /api/v1/contents/[username]/[slug]/children

Teste com 27 comentários na publicação raiz em diferentes níveis (cenário "ok"). Acredito que a diferença de desempenho entre as queries não seja significativa nesse cenário, e os dois exemplos mais demorados abaixo do get_current_balance foram apenas valores discrepantes:

get_current_balance get_current_balance_credit_debit Diferença (%)
55ms 55ms =
57ms 57ms =
57ms 57ms =
112ms 60ms -46%
141ms 62ms -56%

Explain com 27 comentários na publicação: get_current_balance e get_current_balance_credit_debit.

O mesmo teste com 2027 comentários na publicação raiz em diferentes níveis (cenário extremo):

get_current_balance get_current_balance_credit_debit Diferença (%)
186ms 287ms +54%
191ms 295ms +54%
199ms 315ms +58%
213ms 332ms +56%
265ms 348ms +31%

Explain com 2027 comentários na publicação: get_current_balance e get_current_balance_credit_debit.

Parece que a mudança de ROWS 1 não trouxe um impacto relevante nesta query.

POST /contents/[user]/[slug]/tabcoins

get_current_balance get_current_balance_credit_debit Diferença (%)
44ms 44ms =
46ms 45ms -2%
47ms 46ms -2%
51ms 48ms -6%
52ms 55ms +6%

Explain: get_current_balance e get_current_balance_credit_debit.

Continua ótimo, sem diferença significativa entre as duas queries.

Próximos passos

  • GET /api/v1/contents/[username]/[slug]/children continua precisando de melhorias. Citando meu último comentário:

    Com muitos [comentários] (centenas ou milhares, coisa que hoje provavelmente temos em menos de 5 publicações) o impacto é mais significativo.

    Uma das publicações com muitos comentários está referenciada em vários lugares, que é a Tentando construir um pedaço de internet mais massa, então provavelmente é acessada algumas vezes por dia, o que faz com que essa query também mereça atenção, mas não é tão urgente/impactante quanto a anterior.

Outro ponto menos importantes que pode ser avaliado ao resolver o ponto acima:

  • GET /api/v1/contents: com um bom desempenho, podemos retornar (e exibir) os créditos e débitos na lista de conteúdos (conforme comentado aqui).

Além disso, pensei em renomear a função de get_current_balance_credit_debit para get_content_balance_credit_debit, porque no commit 59ea58c a função passou a ter uma condição de considerar apenas eventos do tipo update:content:tabcoins para a contagem.

@aprendendofelipe
Copy link
Collaborator

@Rafatcb, eu acho que ROWS 1 ajuda sim a diminuir o custo da função, mas desconfio que não foi isso que melhorou tanto o desempenho em GET /api/v1/contents/[username]/[slug]. Tentou redefinir a função para a versão anterior (sem ROWS 1) pra ver se o desempenho volta a ficar tão ruim?

De qualquer forma, pode adicionar o ROWS 1 já na definição da função, sem precisar alterar ela em um comando separado.

Sobre os próximos passos, não ficou claro se você planeja fazer no mesmo PR ou em outro. Eu tinha falado em separar a migration em outro PR, mas não precisa, pois já que é apenas uma definição de função, é tranquilo de fazer na mão e não tem problema depois rodar a migration por cima. Tanto que já defini a função (na versão sem ROWS 1) para podermos testar em homologação. Fiz com o nome get_current_balance_credit_debit, mas acho que vale a mudança para get_content_balance_credit_debit.

Sobre o desempenho, eu acho que o caminho envolve melhorar a modelagem dos dados para não precisar usar a tabela de eventos. Isso seria facilmente alcançado com novos valores para balance_type na tabela balance_operations. Separaria o que hoje é content:tabcoin nos três casos, algo como: content:tabcoin:initial, content:tabcoin:credit e content:tabcoin:debit. Só isso já iria permitir usar o índice que já temos em balance_type.

Em um avanço maior, acho que deveríamos ter tabelas separadas para os balanços dos conteúdos e dos usuários, assim como TabCash também deveria ser separado.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 13, 2024

Tentou redefinir a função para a versão anterior (sem ROWS 1) pra ver se o desempenho volta a ficar tão ruim?

Acabei de fazer um teste aqui de quatro execuções consecutivas, primeiro com ROWS 1 e depois com ROWS 1000.

ROWS 1 ROWS 1000
338ms 765ms
65ms 249ms
42ms 248ms
49ms 244ms

Foram as únicas execuções que fiz no banco depois de ter ligado o computador (fora a atualização da função), então isso pode explicar o motivo da primeira execução de cada ter demorado significativamente mais.

De qualquer forma, pode adicionar o ROWS 1 já na definição da função, sem precisar alterar ela em um comando separado.

Eu pensei nisso, mas não descobri como fazer com o createFunction do node-pg-migrate. Você sabe como faz? Ou está dizendo para eu criar a função inteira usando o pgm.sql mesmo?

Sobre os próximos passos, não ficou claro se você planeja fazer no mesmo PR ou em outro.

Sobre o GET /api/v1/contents/[username]/[slug]/children, eu planejava investigar mais para ver se existe alguma melhoria que dê para fazer antes de ir para o merge.

Já no GET /api/v1/contents, nem cheguei a testar como fica o desempenho. Então, posso testar e colocar aqui os resultados. Se não ter impacto negativo significativo, posso retornar na API e exibir na lista de conteúdos com um Tooltip. Se você achar isso desnecessário por ora, posso apenas fazer os testes.

Outro ponto é o texto na UI que também precisa de uma melhoria (meu foco foi o desempenho na última iteração), mas isso já está sendo discutido no issue #1370.

Fiz com o nome get_current_balance_credit_debit, mas acho que vale a mudança para get_content_balance_credit_debit.

Vou mudar no próximo commit 👍

Sobre o desempenho, eu acho que o caminho envolve melhorar a modelagem dos dados para não precisar usar a tabela de eventos. Isso seria facilmente alcançado com novos valores para balance_type na tabela balance_operations. Separaria o que hoje é content:tabcoin nos três casos, algo como: content:tabcoin:initial, content:tabcoin:credit e content:tabcoin:debit. Só isso já iria permitir usar o índice que já temos em balance_type.

Em um avanço maior, acho que deveríamos ter tabelas separadas para os balanços dos conteúdos e dos usuários, assim como TabCash também deveria ser separado.

Vamos supor que eu não consiga melhorar o tempo de execução das queries, e que essa sua proposta seja o caminho. Você acharia melhor implementá-la nesse PR ou deixar para outro, específico sobre isso?

@aprendendofelipe
Copy link
Collaborator

Acabei de fazer um teste aqui de quatro execuções consecutivas, primeiro com ROWS 1 e depois com ROWS 1000.

Muito estranho o impacto ser tão grande em GET /api/v1/contents/[username]/[slug] que só usa a função uma vez, mas não vale a pena investigar isso agora.

De qualquer forma, pode adicionar o ROWS 1 já na definição da função, sem precisar alterar ela em um comando separado.

Eu pensei nisso, mas não descobri como fazer com o createFunction do node-pg-migrate. Você sabe como faz? Ou está dizendo para eu criar a função inteira usando o pgm.sql mesmo?

Pode colocar no returns:

returns: 'TABLE (total_balance BIGINT, total_credit BIGINT, total_debit BIGINT) ROWS 1',

Sobre os próximos passos, não ficou claro se você planeja fazer no mesmo PR ou em outro.

Sobre o GET /api/v1/contents/[username]/[slug]/children, eu planejava investigar mais para ver se existe alguma melhoria que dê para fazer antes de ir para o merge.

Já no GET /api/v1/contents, nem cheguei a testar como fica o desempenho. Então, posso testar e colocar aqui os resultados. Se não ter impacto negativo significativo, posso retornar na API e exibir na lista de conteúdos com um Tooltip. Se você achar isso desnecessário por ora, posso apenas fazer os testes.

Posso estar enganado, mas acho que compensa já ir para a mudança na tabela balance_operations.

Outro ponto é o texto na UI que também precisa de uma melhoria (meu foco foi o desempenho na última iteração), mas isso já está sendo discutido no issue #1370.

Podemos colocar à prova a versão que já está no PR. Tendo os dados disponíveis no front, a forma de apresentação pode ser mudada facilmente, então podemos melhorar depois de acordo com o feedback dos usuários. 👍

Sobre o desempenho, eu acho que o caminho envolve melhorar a modelagem dos dados para não precisar usar a tabela de eventos. Isso seria facilmente alcançado com novos valores para balance_type na tabela balance_operations. Separaria o que hoje é content:tabcoin nos três casos, algo como: content:tabcoin:initial, content:tabcoin:credit e content:tabcoin:debit. Só isso já iria permitir usar o índice que já temos em balance_type.
Em um avanço maior, acho que deveríamos ter tabelas separadas para os balanços dos conteúdos e dos usuários, assim como TabCash também deveria ser separado.

Vamos supor que eu não consiga melhorar o tempo de execução das queries, e que essa sua proposta seja o caminho. Você acharia melhor implementá-la nesse PR ou deixar para outro, específico sobre isso?

Me parece que tanto faz. Mas, se for separar, acho que compensa ser um PR anterior a esse. Se achar que vale a pena ir por esse caminho, eu acho que já tenho uma boa ideia de como poderia ser feito, então posso tentar criar o primeiro PR.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 13, 2024

Podemos colocar à prova a versão que já está no PR. Tendo os dados disponíveis no front, a forma de apresentação pode ser mudada facilmente, então podemos melhorar depois de acordo com o feedback dos usuários. 👍

Ok. Subi a alteração da frase conforme nosso último comentário no issue.

Me parece que tanto faz. Mas, se for separar, acho que compensa ser um PR anterior a esse. Se achar que vale a pena ir por esse caminho, eu acho que já tenho uma boa ideia de como poderia ser feito, então posso tentar criar o primeiro PR.

Pode implementar. Eu consegui testar algumas alterações na query do endpoint GET /api/v1/contents/[username]/[slug]/children, mas nenhuma teve um impacto significativo no tempo de execução. Percebi que algumas mudanças melhoraram o planejamento, outras interpretei como uma piora. Nenhum teste quebrou com as alterações.

Coloquei duas opções de query abaixo. Você pode ver tanto as queries quanto o planejamento com o Explain para o cenário de 2027 comentários nos links.

Original Sem UNION ALL Sem UNION ALL, com INNER JOIN ao invés de subselect
283ms 281ms 319ms
302ms 284ms 330ms
302ms 310ms 333ms
337ms 339ms 338ms
346ms 363ms 342ms
475ms 368ms 344ms

A variação de tempo foi tão pequena que eu suspeito que as diferenças sejam apenas imprecisões, e não necessariamente que uma query ficou melhor que a outra. Minha análise principal foi pelo Explain, o que me levou a optar pela segunda query (sem UNION ALL, mas com subselect) como sendo a "melhor" (subi as alterações com essa query).

Além disso, o EXPLAIN mostra que a maior duração é na Function scan, então creio que as alterações que você propôs terão impactos mais significativos no desempenho.

Por desencargo, fiz o teste também no cenário com 27 comentários, também sem alterações significativas:

Original Sem UNION ALL Sem UNION ALL, com INNER JOIN ao invés de subselect
55ms 55ms 52ms
55ms 56ms 53ms
56ms 56ms 70ms
65ms 71ms 73ms
72ms 76ms 75ms
107ms 89ms 81ms

PS: Eu percebi apenas depois dos testes acima que não precisava do parent.* no SELECT, porque são os mesmos campos do c.*, então eu removi o parent.* no commit.

@aprendendofelipe
Copy link
Collaborator

Pode implementar.

Logo subo o PR 👍🤝

Acho que vou colocar também a versão atualizada de get_content_balance_credit_debit, pois assim esse PR aqui não fica dependente de nenhuma migration.

Eu consegui testar algumas alterações na query do endpoint GET /api/v1/contents/[username]/[slug]/children, mas nenhuma teve um impacto significativo no tempo de execução. Percebi que algumas mudanças melhoraram o planejamento, outras interpretei como uma piora. Nenhum teste quebrou com as alterações.

Coloquei duas opções de query abaixo. Você pode ver tanto as queries quanto o planejamento com o Explain para o cenário de 2027 comentários nos links.

Acho que a query original, com UNION ALL, é melhor, mas a diferença é insignificante. Sem UNION ALL você busca duas vezes o conteúdo alvo, o que é muito rápido, mas não tem porque buscar duas vezes. Fora essa busca extra, tudo deve funcionar igual, desde que o PostgreSQL use o índice corretamente em path.

A variação de tempo foi tão pequena que eu suspeito que as diferenças sejam apenas imprecisões, e não necessariamente que uma query ficou melhor que a outra. Minha análise principal foi pelo Explain, o que me levou a optar pela segunda query (sem UNION ALL, mas com subselect) como sendo a "melhor" (subi as alterações com essa query).

É isso, vai ser muito pouca diferença, mas deve ser para pior.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 13, 2024

Acho que a query original, com UNION ALL, é melhor, mas a diferença é insignificante. Sem UNION ALL você busca duas vezes o conteúdo alvo, o que é muito rápido, mas não tem porque buscar duas vezes. Fora essa busca extra, tudo deve funcionar igual, desde que o PostgreSQL use o índice corretamente em path.

Ah, investigando mais a fundo, entendi. Acha melhor deixar com o UNION ALL, então? Posso mudar isso de volta quando for realizar o rebase após o merge do seu PR.

@aprendendofelipe
Copy link
Collaborator

Acha melhor deixar com o UNION ALL, então? Posso mudar isso de volta quando for realizar o rebase após o merge do seu PR.

Acho que é melhor deixar com UNION ALL. 👍

PR #1624 aberto e a função get_content_balance_credit_debit já está disponível em homologação. Ela só recebe o ID do conteúdo como parâmetro, e o retorno é o mesmo da versão atual desse PR. A princípio a migration não é mais necessária nesse PR.

Return TabCoins credits and debits when returning a content and when qualifying a content. The
TabCoin initially earned by publishing the content is not considered when counting the
`tabcoins_credit`. The `tabcoins_debit` is 0 or a negative number.
@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 18, 2024

Decidi deixar padronizado para retornar o tabcoins_credit e o tabcoins_debit sempre que retorna tabcoins no conteúdo, assim a API fica mais consistente.

Criei um componente para exibir a Tooltip para garantir que o texto seja consistente independentemente de onde é exibido.

Lista de conteúdos Conteúdo
Página da lista de conteúdos Página do conteúdo

Retornei tabcoins_credit e tabcoins_debit no POST /api/v1/contents apenas para padronizar esses retornos. Com isso, também chamei a função getContentTabcoinsCreditDebit, que não é necessária, pois poderíamos sempre retornar 0 para as propriedades mencionadas, mas chamando a função o código fica mais "à prova do futuro".

Aproveitei para tirar o .skip do teste With 20 simultaneous posts, but enough TabCoins for 1 em /api/v1/contents/[username]/[slug]/tabcoins/post.test.js, porque de acordo com o nome do teste, a restrição do IP não entraria em vigor (apenas um voto seria computado).

Aproveitei para atualizar a descrição do PR. Pronto para revisão e potencial merge 👍

@Rafatcb Rafatcb marked this pull request as ready for review February 18, 2024 01:51
Copy link
Collaborator

@aprendendofelipe aprendendofelipe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Show, concordo com todas as últimas melhorias! 👍👍👍

Só veja se faz sentido minha sugestão no código ou se mantemos assim. Não é nada demais.


Testando esse PR em homologação eu percebi que alguns conteúdos estavam com dados estranhos, e pareciam ter 2 TabCoins iniciais (veja este exemplo).

Investigando isso, descobri que, em homologação, 111 conteúdos criados entre 01 e 03/07/2022 realmente ficaram com dois TabCoins iniciais, pois o script que o Filipe rodou para creditar os conteúdos antigos acabou duplicando os créditos nesse conteúdos. Isso deve ter ocorrido, provavelmente, porque nesse período existiam versões em homologação rodando em paralelo, algumas que creditavam e outras que ainda não creditavam TabCoins, então deve ter sido uma decisão entre duplicar alguns ao invés de deixar outros sem nenhum crédito inicial.

Então é isso, 111 conteúdos em homologação tem 2 TabCoins iniciais, mas em produção está tudo certo. 👍


Só que essa verificação acima me fez perceber que faltou um detalhe no UPDATE de balance_operations, pois as transações desfeitas devido ao banimento de usuários ficaram como content:tabcoin:initial, quando o correto era ser content:tabcoin:credit ou content:tabcoin:debit, e com sinais trocados, ou seja, para desfazer um crédito indevido, é criado um novo crédito com o valor negativo.

Já vou atualizar meu comentário no #1624 que descreve os scripts que devem ser executados para o UPDATE de balance_operations. Eu já rodei os scripts e fiz também o REINDEX. 👍

pages/interface/components/TabCoinBalanceTooltip/index.js Outdated Show resolved Hide resolved
On hover, display TabCoins credits, debits and the percentage of credits in relation to the total.
@aprendendofelipe aprendendofelipe merged commit 6076989 into main Feb 18, 2024
7 checks passed
@aprendendofelipe aprendendofelipe deleted the return-content-tabcoins-credits-and-debits branch February 18, 2024 17:03
@aprendendofelipe
Copy link
Collaborator

Em produção! 🚀🚀🚀

@aprendendofelipe
Copy link
Collaborator

Fiz Rollback porque estava gerando erros de validação, o que impedia a exibição de alguns conteúdos.

O problema é que alguns conteúdos de usuários banidos ficaram com créditos negativos, pois a reversão do crédito inicial ficou como content:tabcoin:credit negativo, quando deveria ser content:tabcoin:initial negativo.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 18, 2024

Entendi.

Existe algum conteúdo de usuário banido que ainda está na plataforma? Eu sei do problema de banir usuários com muitos conteúdos, que precisa apagar os conteúdos manualmente por causa do tempo da query, mas não sabia que conteúdos sem usuários ainda eram listados.

@aprendendofelipe
Copy link
Collaborator

Existe algum conteúdo de usuário banido que ainda está na plataforma?

Não é para ter nenhum. Está dando problema com os filhos dos conteúdos excluídos.

@Rafatcb
Copy link
Collaborator Author

Rafatcb commented Feb 18, 2024

As novas ações estão funcionando normalmente, o problema é apenas o UPDATE em balance_operations dos conteúdos antigos, certo?

@aprendendofelipe
Copy link
Collaborator

As novas ações estão funcionando normalmente, o problema é apenas o UPDATE em balance_operations dos conteúdos antigos, certo?

Era isso sim, mas já está resolvido. Acabei de voltar a versão desse PR para produção. 🎉🎉🎉

Já atualizo de novo o #1624 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
back Envolve modificações no backend front Envolve modificações no frontend novo recurso Nova funcionalidade/recurso
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mostrar quantidade de votos positivos e negativos, em vez de apenas o total
2 participants