josircg / raizcidadanista

Sistema de Gerenciamento da Raiz Cidadanista
http://www.raiz.org.br
GNU General Public License v3.0
1 stars 2 forks source link

Controle Tópico Lido/Não Lido #79

Closed josircg closed 8 years ago

josircg commented 8 years ago

Uma das funções mais importantes para o usuário é que ele possa saber rapidamente quantas conversas ocorreram para um determinado grupo ou tópico.

Se coloque sempre no lugar do usuário: eu acabo de entrar no fórum e tenho uns 10 grupos inscritos. Quero saber quantos grupos tiveram alguma conversação. E quando entrar no grupo, quero saber quantos tópicos tiveram conversação.

1) sempre que o usuário entra no tópico, este deve marcado com lido para o usuário corrente.

2) Podemos fazer o controle pela data de último acesso ou comparando o número de mensagens antes e depois. Na primeira alternativa, o ideal é que tenhamos um método no tópico que retorne o número quantas mensagens foram trocadas desde a última vez que o usuário visitou o tópico.

A segunda opção seria fazer o controle pelo número de mensagens. quando o usuário entrar em um tópico eu registro o número de mensagem que ele leu. Ex.: 5. Mais tarde quando o usuário foi ver a lista de tópicos, eu pego o número de mensagem do tópico corrente menos o número de mensagens lidas pelo usuário, estas seriam as mensagens não lidas. Dessa forma não precisa ser feito o controle por datas, pois não vamos precisar saber quais a que ele leu ou não, apenas o número de não lidas.

A desvantagem em termos de performance dessa segunda alternativa é que eu terei SEMPRE que contar quantas mensagens existem em CADA grupo. Na primeira alternativa, eu não faço essa contagem. Eu simplesmente uso a data corrente X a data de último acesso do usuário, ou seja, acesso menos o BD.

leonardocsantoss commented 8 years ago

Na verdade as duas opções realizam o mesmo número de consultas, na primeira opção:

  1. Será consultado a data da ultimo acesso;
  2. Com a data do ultimo acesso será feito um filtro, pegando o número de Conversas do tópico cuja data for maior que a data do ultimo acesso.

Na segunda opção:

  1. Será consultado o número de Conversas lidas;
  2. Será consultado o número de Conversas do tópico.

O custo de processamento da segunda opção é menor, pois é um filtro a menos.

Acabei fazendo essa issue dentro desta: #78

josircg commented 8 years ago

1) Performance: o problema que vc não prestou atenção é no tamanho de cada dataset consultado:

No primeiro algoritmo, eu faço 2 acessos ao banco:

  1. A data de último acesso de um usuário: pk
  2. TopicoOuvinte de um determinado usuário e filtro pela data. Ou seja, eu uso apenas um índice sem precisar fazer um Full Table Scan filtrando pelo contador.

Na segunda opção: Eu tenho que varrer todos os TópicosOuvinte (Full Table Scan) fazendo um Join com Topico verificando em cada um deles se o número está menor que o outro. Não esquece que um usuário poderá participar de centenas de tópicos ativos.

A gente tem que ficar MUITO atento desde o início com as questões de performance pois esse sistema deverá ter um número muito grande de usuários e tópicos.

leonardocsantoss commented 8 years ago

Segui a primeira ideia. Só para ficar documentado:

  1. Adicionei o campo TopicoOuvinte.dtleitura
  2. Coloquei um signal para adicionar o TopicoOuvinte para todos os usuário de um grupo sempre que um tópico for adicionado, e para um usuário sempre que ele for adicionado no grupo.
  3. Ao entrar no tópico é registrado o TopicoOuvinte.dtleitura = now
  4. A lógica do número de conversas não lidas foi: conversa.filter(dt_criacao__gt=TopicoOuvinte.dtleitura).count()
  5. A lógica do número de tópicos não lidos foi: Todos os tópicos cujas conversas não lidas > 0