Рассмотрю буквально парочку малоизвестных нюансов/подводных камней.
Мало кто знает, что для вычитки файла в строку можно использовать такой код:
my $content = do {local (@ARGV, $/) = $filename; <ARGV> };
За объяснениями в perldoc perlvar и поиск по ARGV.
Такой подход использовался и в File::Slurp. В данной ситуации не просходит flock, это важно учитывать если Вы этот файл еще и пишите другим процессом . Проблему конкурентной записи можно решить и без flock, просто нужно операцию записи сделать атомарной(File::Slurp поддерживает для этих целей флаг "atomic").
Идея заключается в следующем:
- Создается уникальный временный файл и в него пишутся данные
- Временный файл переименовывается в целевой файл. Операция rename в большинстве ОС - атомарная.
И казалось бы все отлично, но лишь до того момента когда вы начнете использовать NFS :)
Операция rename в NFS - атомарная, но есть следующий нюанс. Если вы делаете rename и файл назначения уже существует, то сначала удаляется файл назначения, а затем лишь происходит rename. И это ДВЕ ОТДЕЛЬНЫЕ операции.
В результате если у Вас один процесс читает файл, а другой его периодически обновляет, то возможна ситуация когда читающий процесс просто не увидит файл.