Devo me preocupar com condições de corrida com transferência/processamento SFTP?

Devo me preocupar com condições de corrida com transferência/processamento SFTP?

Cenário:

Estou usando SFTP para transferir arquivos automaticamente entre dois sistemas, A e B.

O sistema A executa um servidor SFTP. O Sistema A irá periodicamente (digamos, uma vez por minuto) pesquisar seu diretório SFTP local para verificar a existência de arquivos *.dat e, se encontrados, importá-los e excluí-los.

O Sistema B gera arquivos *.dat e, à medida que são gerados, os envia para o Sistema A conectando-se a esse host SFTP e fazendo upload deles.

Questões:

  1. É possível que o Sistema A veja e comece a processar um arquivo antes que o Sistema B termine de carregá-lo? Ou o SFTP impedirá isso de alguma forma, como não depositar arquivos na pasta até que a transferência pela rede termine?

  2. É razoável/recomendado que o Sistema B faça upload com outro nome de arquivo, como *.locked ou *.part, e depois renomeie para *.dat após a conclusão da transferência de rede? Ou existe uma maneira melhor de lidar com isso?

Responder1

Não é uma condição de corrida por definição, porém é possível que um arquivo, parcialmente carregado, seja aberto para leitura pelo Sistema A e, portanto, contenha dados inválidos. O sistema A pode verificar a consistência do arquivo, pode testar um tamanho fixo, se apropriado, pode testar certas permissões de arquivo (que você define após o upload) e, em qualquer caso, adiar a abertura do arquivo caso as condições não sejam atendidas, fazendo isso na próxima iteração.

Eu faria upload para um nome de arquivo ou local temporário e depois renomearia/moveria para a pasta/extensão correta do seu programa. ou seja, carregue para filename.part e depois renomeie para filename.dat ou carregue para pendente/filename.dat e depois saia da pasta pendente. Isso resolverá esses problemas. Em sistemas UNIX/Linux e Windows, uma operação de movimentação (ou operação de renomeação) será atômica e você nunca obterá um arquivo parcial.

Não há maneira melhor de lidar com isso. Você precisa comunicar ao Sistema A que o arquivo não está completo e não possui nenhuma comunicação entre processos configurada entre os sistemas. Suas opções são usar um arquivo de bloqueio para evitar que seu programa abra o arquivo (e depois removê-lo), usar um arquivo temporário (e então renomear/mover seu arquivo para o nome apropriado) ou fazer algum tipo de verificação de integridade (que é provavelmente um desperdício de recursos).

Você também pode considerar, dependendo da frequência com que isso ocorre, acionar o Sistema A do Sistema B. Se houver um arquivo lá 99% das vezes, a maneira que você já propõe (com um bloqueio) é provavelmente a mais eficiente. Por outro lado, se você encontrar dados apenas ocasionalmente, isso pode ser um desperdício de recursos (e exigir um programa de longa duração ou acionado pelo cron). Se você tiver SFTP, poderá ter acesso SSH. Nesse caso, configure certificados entre o sistema (para evitar a necessidade de senhas, consulte ssh-copy-id) e execute alguma versão modificada do

ssh system_a.seudominio.com 'processfile /home/user/data/*.dat'

informação relacionada