2009-09-22 2 views
5

При развертывании Rails через Passenger или Mongrel у вас есть несколько экземпляров запущенного приложения. Какова наилучшая практика или шаблон для создания мьютекса на общих ресурсах, таких как запись в локальный файл или удаленный файл. Я хочу, чтобы два процесса не записывались на один и тот же ресурс одновременно.Mutex for Rails Processes

ответ

14

Если вам просто нужно, чтобы предотвратить появление нескольких авторов от работы с файлом одновременно, вы можете использовать метод File#flock запросить эксклюзивную блокировку записи от каждого процесса:

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 

Примечание: поставить вызов разблокировки в Блок ensure является важным для предотвращения взаимоблокировки, если после того, как вы заблокировали файл, вы выбрали неперехваченное исключение.

+1

Отличное объяснение. –

+1

Как проверить, заблокирован ли файл? Я хочу использовать файл как глобальную блокировку, #flock кажется прекрасным, но другой процесс должен проверить, доступен ли он, как мне это разрешить? –

+0

@HarisKrajina, файл заблокирован, если 'flock (Файл :: LOCK_EX | File :: LOCK_NB)' возвращает 'false'. Документы см. В разделе «ri File.flock». –

2

Насколько я знаю, единственный способ сделать это в такой среде - использовать семафор на основе файлов - коснуться файла блокировки, выполнить свою работу, удалить файл блокировки. Сделайте процесс неудачным, если в файле есть блокировка.

У вас также может быть служба, которая записывает в файл с потоковой передачей, а приложения обращаются к службе, чтобы изменить файл, а не позволять им напрямую изменять файл.