Two TILs in one, how to use native file locking to prevent more than one process running at the same time.

Here I'll grab a file and create an exclusive lock.

file = File.new('process.lock')
file.flock(File::LOCK_EX)
# do something exclusively
file.flock(File::LOCK_UN)

If two process are running concurrently, the first one to hit line 2 gets an exclusive lock. The second process waits until it can get a lock. The lock is released at line 4 (which really should have an ensure to make sure it gets executed).

What happens if I want to fail fast?

file = File.new('process.lock')
file.flock(File::LOCK_EX | File::LOCK_NB) or abort 'Already running'

The LOCK_NB is a flag to indicate non-blocking. The second process will fail to get the lock but then fail-fast.

The __DATA__ File

Imagine I had a file like this:

DATA.flock(File::LOCK_EX | File::LOCK_NB) or abort 'Already running'
__END__
Sentinel for locking

After a __END__ (that two underscores before and after the END) the content become available via the special DATA variable which is an IO like object. With this trick, I can have exclusive locks without needing a special lock file.