Mutex for Rails Processes

2019-02-10 11:31发布

问题:

When deploying Rails via Passenger or Mongrel you have multiple instances of the application running. What is the best practice or pattern to establish a mutex on shared resources such as a writing to a local file or to a remote file. I want to ensure two processes are not writing to the same resource at the same time.

回答1:

If you just need to prevent multiple writers from working with a file simultaneously, you can use the File#flock method to request an exclusive write lock from each process:

fh = File.new("/some/file/path")
begin
  fh.flock(File::LOCK_EX)
  # ... write to the file here, or perform some other critical operation
ensure
  fh.flock(File::LOCK_UN)
end

Note: putting the unlock call in an ensure block is important to prevent deadlock if an uncaught exception is thrown after you've locked the file.



回答2:

As far as I know, the only way to do this in an environment like this is to use a file-based semaphore - touch a lockfile, do your work, remove the lockfile. Make the process fail if there's a lock on the file.

You could also have a service that writes to the file that is threaded, and make the apps talk to the service to modify the file rather than letting them modify the file directly.



回答3:

You could use a background job scheduler to do the actual work, for example delayed_job (http://github.com/tobi/delayed_job).