0

So I have SVN installed on our web server. The idea is that the working copies are loaded on developer machines and when they commit (conflicts asside) the server executes a post-commit bash.

Repositories are per project based, the idea is that upon post-commit, the bash file needs to force delete the entire project folder and files, and export the updated repo back into the project folder, to keep the website updated via SVN... I know there's bound to be some disagreements with this method but it works for us... except for ONE thing...

While the server is re-exporting the project, any requests being made to the website raise errors since there's chunks of files missing... Is there any way to "queue" apache/php while SVN exports, and then "resume" the requests?

The server exports the files pretty quickly but it's those few millisecs that someone catches the server and raises PHP errors...

Please let me know if there's a typical method to sort this out...

Thanks

4

4 回答 4

2

您可以通过在新目录树中构建内容然后重命名内容来最大限度地减少中断。也就是说,假设您的内容在 下可用/var/www/myproject,您的更新后脚本将:

  • 填充/var/www/myproject.new
  • 重命名/var/www/myproject/var/www/myproject.old
  • 重命名/var/www/myproject.new/var/www/myproject
  • 删除/var/www/myproject.old

虽然不是原子更新,但执行两次重命名所需的时间将很短,应该会大大改善这种情况。

于 2012-12-01T18:33:47.107 回答
1
  1. 您不能导出整个树,而只能导出受此修订影响的文件,并在不删除站点的情况下替换文件
  2. 您仍然可以执行完全导出和完全替换,但不能在挂钩中删除站点,只能覆盖旧文件(在修订文件中删除,您在站点上保持完整,不会破坏它,因为它们不相关)并执行完整在夜间 cron-job 中同步(每天或每周)
于 2012-12-02T04:09:03.083 回答
0

我真的觉得@Larsks 的回答足够实用,可以在当时提供一个几乎原子且需要的解决方案,所以我将他的回答保持为“正确”,但我认为我也会考虑这篇文章

假设 mv 是完全原子的,提交后挂钩 bash 可能如下所示:

svn export file:///svn/repo /var/www/projectdir_NEW --force
mv /var/www/projectdir /var/www/projectdir_OLD
mv /var/www/projectdir_NEW /var/www/projectdir
rm -rf mv /var/www/projectdir_OLD

唯一的问题是 2 mv 命令之间的几秒钟,这是最接近原子和最干净的方法......但是,对于完全原子的影响,假设我不介意使用一点 PHP 和因为我的项目有一个全局 init.php,post-commit 可以这样做:

date > /var/www/projectdir.updating
svn export file:///svn/repo /var/www/projectdir_NEW --force
mv /var/www/projectdir /var/www/projectdir_OLD
mv /var/www/projectdir_NEW /var/www/projectdir
rm -rf mv /var/www/projectdir_OLD
rm /var/www/projectdir.updating

创建一个名为“projectdir.updating”的临时文件,其中包含日期,执行更新,然后删除临时文件,我现在可以使用我的 init.php 来“限制”任何请求:

while (file_exists("/var/www/projectdir.updating")) usleep(200);

此外,我可以检查保存在临时文件中的日期详细信息是否有错误退出...(如果导出无法删除 .updating 文件)

于 2012-12-02T21:12:37.017 回答
0

我不知道以下内容是否对您有用,但您可以制作一个两步代码升级脚本:

  1. tempdir 中的 SVN 结帐
  2. 将生产目录中的所有代码替换为 tempdir 中包含的数据
  3. 删除临时目录

你永远不会经历冲突。

顺便说一句,我认为这不是最佳做法。您应该解决客户端开发人员机器上的冲突。

于 2012-12-01T18:36:37.760 回答