Di-Ca-N / dropbox

Sistema simples de sincronização de arquivos.
MIT License
0 stars 0 forks source link

Implement client to server sync #10

Closed felipe-gallois closed 3 months ago

felipe-gallois commented 4 months ago

This PR implements client to server sync feature to the client. Some things done here include:

  1. Added a new dedicated socket to the client
  2. Changed some errors messages to more accurate outputs
  3. Implemented Sync Client to Server protocol
  4. Implemented an EventHistory module to avoid resending updates to the server
  5. Adapted existing code to support the functionality
Di-Ca-N commented 3 months ago

Também precisei mudar o fluxo de autenticação para incluir um device id, para poder saber quais conexões de sincronização que vêm do mesmo dispositivo

felipe-gallois commented 3 months ago

Em especial, precisei alterar o jeito como o ServerMonitor coloca os eventos na EventHistory, para resolver uma race condition. Agora é garantido que o evento vai ser colocado no histórico antes de ele de fato ser executado, para evitar de o ClientMonitor ver o evento do inotify antes do ServerMonitor colocar o evento no histórico.

Eu proponho uma solução alternativa para esse problema. Se receiveFileData, do módulo Messages, colocasse seu output em um std::ostringstream, evitando que o conteúdo fosse imediatamente gravado em disco, poderíamos usar um mutex no ServerMonitor para proteger as escritas tanto do arquivo no disco como da operação no histórico. Eu particularmente gosto mais dessa solução para evitar a dependência do EventHistory em Connection, que eu acho inapropriada.

Di-Ca-N commented 3 months ago

Também não gostei da dependência. Acho que essa é uma solução interessante, mas manter o arquivo inteiro em memória antes de gravar no disco dificultaria a transferência de arquivos grandes.

Outras alternativas que vejo:

  1. usar um arquivo temporário fora da pasta de sincronização para fazer o papel do string stream, e só mover esse arquivo para dentro da pasta sincronizada depois de colocar o evento no histórico.

  2. voltar ao design original de separar a Connection em três classes, uma para cada função. Aí só uma dessas classes teria a dependência do EventHistory

felipe-gallois commented 3 months ago

Outras alternativas que vejo:

  1. usar um arquivo temporário fora da pasta de sincronização para fazer o papel do string stream, e só mover esse arquivo para dentro da pasta sincronizada depois de colocar o evento no histórico.
  2. voltar ao design original de separar a Connection em três classes, uma para cada função. Aí só uma dessas classes teria a dependência do EventHistory

A primeira opção me parece mais agradável. Vais fazer isso, ou queres que eu faça?

Di-Ca-N commented 3 months ago

A primeira opção me parece mais agradável.

A única ressalva que tenho é que isso vai aumentar a latência entre receber um arquivo e o usuário ver alguma coisa acontecendo na tela. É só uma questão de user-experience, mas isso pode dar a impressão de que o sistema não está fazendo nada. Será que isso é um problema?

Vais fazer isso, ou queres que eu faça?

Agradeço se puder fazer a implementação

Di-Ca-N commented 3 months ago

Talvez dê pra colocar o arquivo temporário dentro da própria pasta sync_dir, mas com um sufixo especial (tipo arquivo.txt.transfer, arquivo.txt.tmp, ou algo do gênero), e fazer o ClientMonitor ignorar os eventos dos arquivos que terminem com esse sufixo. Daí pelo menos vai aparecer alguma coisa na pasta durante a transferência, mas o que vai aparecer seria um arquivo "estranho"... não sei se melhora muito.

felipe-gallois commented 3 months ago

Talvez dê pra colocar o arquivo temporário dentro da própria pasta sync_dir, mas com um sufixo especial (tipo arquivo.txt.transfer, arquivo.txt.tmp, ou algo do gênero), e fazer o ClientMonitor ignorar os eventos dos arquivos que terminem com esse sufixo. Daí pelo menos vai aparecer alguma coisa na pasta durante a transferência, mas o que vai aparecer seria um arquivo "estranho"... não sei se melhora muito.

Certo. Sabe que eu até acho que alguns serviços de nuvem fazem isso?

Di-Ca-N commented 3 months ago

Legal! Nesse caso, acho que deve ser uma boa solução.