views:

97

answers:

4

When we build web software releases, we prepare the release in a temporary directory and then replace the release directory with the temporary one just prepared:

# Move and replace existing release directory.
mv /path/to/httpdocs /path/to/httpdocs.before
mv /path/to/$newReleaseName /path/to/httpdocs

Under this scheme, it happens that with about 1 in every 15 releases, a user was using a file in the original release directory exactly at the time the commands above are run, and a fatal error occurs for that user.

I am wondering if using symlinking like follows would be significantly faster, in terms of processing time, thereby helping to lessen the likelihood of this problem:

# Remove and replace existing release symlink.
ln -sf /path/to/$newReleaseName path/to/httpdocs
+1  A: 

Seems to me that since mv in Linux is just a change to the inode information, and ln is copying an inode record, they should both be of quick enough duration that you could not tell the difference with a stopwatch.

But I wonder if they would actually solve your problem. I am guessing that you are saying that users were using the destination files -- so wouldn't it just fail either way?

MJB
If ln is "noticeably" faster, then I would think the problem would present itself less.
Chad Johnson
+4  A: 

The main advantage of using the symlink is that you can do it atomically. Forcing a new symlink is not atomic, but you can create a new symlink and then rename the it to the existing one. The rename is an atomic operation, so you should have no race condition there.

ln -s /path/to/newrelease /path/to/httpdocs.tmp && mv -Tf /path/to/httpdocs.tmp /path/to/httpdocs
Lukáš Lalinský
+1  A: 

It'll definitely be faster if you're moving across partitions. In the same partition I'd guess that it's still going to be smoother to use a link.

My advice is to time it - something like this:

#!/bin/bash
for i in $(seq 1 1000); do
   time mv /path/to/httpdocs /path/to/httpdocs.before
   time mv /path/to/$newReleaseName /path/to/httpdocs
done

for i in $(seq 1 1000); do
   time ln -sf /path/to/$newReleaseName path/to/httpdocs
done

Better to gather real metrics than guess.

Peter Stone
My tests show that mv takes 0.019s at most, while ln takes 0.006s at most, locally.
Chad Johnson
A: 

Be aware that symlinks can be a bit slower: http://httpd.apache.org/docs/2.0/misc/perf-tuning.html

It may solve one problem and create another.

jckdnk111