Eu entendo o conceito geral de bloqueio de arquivo, mas temo que os detalhes me escapem. Quero abrir um arquivo para escrita, obter um bloqueio exclusivo, mas esperar alguns segundos antes de desistir de obter o bloqueio. Cheguei até aqui:
File.open(path, 'a') do |file|
if file.flock(File::LOCK_EX | File::LOCK_NB)
file.seek(0, IO::SEEK_END)
file.write('my content')
else
puts "Could not acquire lock, another process is using the file"
end
end
Como faço para esperar o bloqueio por x segundos?
Você pode configurar um tratamento de timeout você mesmo, similar ao código a seguir. Aqui, abrimos o arquivo e tentamos bloqueá-lo. Se o bloqueio falhar, dormimos 0,1 segundo e tentamos novamente até termos esperado no máximo 5 segundos (por padrão). Se o timeout atingir, levantamos um erro.
Note que ao abrir um arquivo no modo append, o sistema operacional já garante que gravações simultâneas no mesmo arquivo não se sobreponham. Assim, se vários processos abrirem um arquivo no modo append, eles podem simplesmente gravar nele sem nenhum bloqueio adicional.
Entretanto, se algum processo gravar no arquivo em um modo diferente de append, isso não será mais válido e você provavelmente verá corrupção.
Além disso, alguns sistemas de arquivos de rede (como NFS ou sistemas de arquivos must fuse) podem não garantir essa propriedade (mas provavelmente também não suportarão flock). SMB/CIFS é seguro aqui.
Em qualquer caso, ao abrir um arquivo no modo append, não é necessário procurar até o fim, pois o ponteiro do arquivo é automaticamente definido para o fim do arquivo. Pelo contrário, a busca pode ter um efeito negativo, pois pode causar gravações sobrepostas (isto é: desde que a busca seja realmente processada, o que não tenho certeza se é possível com um arquivo aberto no modo append.)
Você pode usar Timeout .
Se a obtenção de um bloqueio demorar mais de 0,5 segundos, isso gerará um Timeout::Error com a mensagem fornecida.