Para aqueles que lêem esta velha questão, é possível, mas requer muitos links simbólicos.
Minha resposta é baseada na de Clinton Blackmore (a resposta atualmente aceita).
Vários diretórios (ou vários arquivos, para esse assunto) não podem ser alterados atomicamente. Portanto, não podemos usar diretórios diretamente. Arquivos únicos podem ser atualizados atomicamente usando a chamada de sistema rename () substituindo o arquivo antigo pelo novo. Os links simbólicos podem ser atualizados da mesma maneira, usando mv -T
para permitir que mv
não desreferencie o destino.
Então, se tivermos esses diretórios:
/srv/dirA/
/srv/dirB/
/srv/dirC/
Podemos fazer com que todos sejam links simbólicos para três outros diretórios:
/srv/dirA -> /version/current/dirA
/srv/dirB -> /version/current/dirB
/srv/dirC -> /version/current/dirC
/version/current
, por sua vez, é apenas um link simbólico para o diretório com a versão atual:
/version/current -> /version/22/
Toda a aplicação web pode então ser atualizada com dois comandos simples, dos quais o último 'substitui' todos os três diretórios de uma só vez (ele não substitui os diretórios, apenas substitui onde esses diretórios apontam):
$ ln -s /version/23/ /version/next
$ mv -T /version/next /version/current
Eu não testei isso, mas deve funcionar. O sinalizador -T
pode ser um sinalizador não padrão. Como alternativa, python -c "import os; os.rename('/version/next', '/version/current')"
pode ser usado no lugar (também não testado).
Eu não sei qual será o impacto no desempenho, mas duvido que seja significativo se você já estiver executando o Django. Eu acho que pode ser importante se você está servindo grandes quantidades de arquivos estáticos com a menor latência possível (como CDNs), e mesmo assim, provavelmente, será apenas um pequeno impacto no desempenho. Em suma, você não precisa se preocupar com o desempenho.
Note que existem algumas armadilhas: o Django é um servidor e não será reiniciado exatamente ao mesmo tempo. Para que isso seja verdadeiramente atômico, o Django teria que ser configurado de uma maneira que pularia completamente a noção de 'versão atual'. Em vez disso, você iniciaria o Django a partir da versão atual para uso em produção. Para atualizar, a próxima versão seria iniciada, então o servidor seria reiniciado (suponho que a maioria dos servidores da Web tenha alguma forma de reiniciar sem ficar offline), e todo o processo deve ser atômico. Mas eu não sou especialista nessa área.
Outra pegadinha (como mencionado por Ptolemy) é que em um servidor ocupado, serão algumas pessoas que vêem páginas parcialmente de uma versão e parcialmente da outra, devido ao cache e ao fato de que vários recursos são solicitados em momentos diferentes durante o pageload (pode haver alguns segundos entre as cargas de recursos). Penso nos dois, o caching será o mais importante, mas também o mais fácil de se trabalhar. Eu duvido que isso seja um grande problema na prática.