Нет, это невозможно. Причины довольно фундаментальны для его дизайна. TL;DR заключается в том, что клиенту намного сложнее, чем вы думаете, правильно обрабатывать эти отдельные события, и почти во всех случаях они вам на самом деле не нужны.
Большинство систем слежения за файлами представляют собой абстракции, которые просто преобразуют специфичную для системы информацию об уведомлении в некоторую общую форму. Они не очень хорошо справляются или вообще не справляются с переполнением очереди уведомлений и не предоставляют своим клиентам способ надежно отреагировать на эту ситуацию.
Вдобавок к этому файловая система может подвергаться многим и разнообразным изменениям за очень короткий промежуток времени и из-за нескольких параллельных потоков или процессов. Это делает эту область чрезвычайно подверженной TOCTOU проблемам, с которыми трудно справиться. Например, создание и запись в файл обычно приводит к серии уведомлений о файле и содержащем его каталоге. Если файл удаляется сразу после этой последовательности (возможно, это был промежуточный файл на этапе сборки), к моменту появления уведомлений о создании файла велика вероятность, что он уже удален.
Watchman принимает входной поток уведомлений и передает его в свою внутреннюю модель файловой системы: упорядоченный список наблюдаемых файлов. Каждый раз, когда получено уведомление, сторож воспринимает его как сигнал к тому, что он должен пойти и просмотреть файл, который был сообщен как измененный, а затем переместить запись для этого файла в самый последний конец упорядоченного списка.
Когда вы запрашиваете у Watchman информацию о файловой системе, возможно или даже вероятно, что могут быть ожидающие уведомления от ядра. Чтобы минимизировать TOCTOU и обеспечить актуальность его состояния, watchman создает файл cookie синхронизации и ожидает, пока это уведомление станет видимым, прежде чем ответить на ваш запрос.
Сочетание двух вышеуказанных вещей означает, что данные результатов сторожа имеют два важных свойства:
- Вы гарантированно просмотрели все уведомления, которые произошли до вашего запроса.
- Вы получаете самую последнюю информацию для любого данного файла только один раз в результатах запроса (результаты изменений объединяются вместе)
Давайте поговорим о случае переполнения. Если ваша система не справляется со скоростью изменения файлов (например, у вас большой проект, и вы очень быстро создаете и удаляете файлы, а система сильно загружена), ОС не может вместить все ожидающие изменения. уведомления в буферных ресурсах, выделенных часам. Когда это происходит, он сбрасывает эти буферы и отправляет сигнал переполнения. Это означает, что клиент наблюдающего API пропустил некоторое количество событий и больше не синхронизируется с состоянием файловой системы. Если этот клиент поддерживает состояние файловой системы, оно больше недействительно.
Watchman решает эту проблему, повторно исследуя отслеживаемое дерево и синтетически помечая все файлы как измененные. Это заставляет следующий запрос от клиента видеть все в дереве. Мы называем это результирующим набором свежий экземпляр, потому что это то же самое представление, которое вы получите при первом запросе. Мы устанавливаем флаг в результате, чтобы клиент знал, что это произошло, и мог предпринять соответствующие шаги для исправления своего состояния. Это поведение можно настроить с помощью параметров запроса.
В этих наборах результатов свежий экземпляр мы не знаем, действительно ли изменился какой-либо данный файл или нет (возможно, он изменился таким образом, что мы не можем обнаружить с помощью lstat
), и даже если мы видим, что его метаданные изменились, мы не знаем причину этого изменения.
Может быть несколько событий, которые влияют на то, почему данный файл появляется в результатах, предоставленных сторожем. Мы не записываем их по отдельности, потому что мы не можем отслеживать их с неограниченной историей; представьте себе файл, который постепенно записывается один раз в секунду в течение всего дня. Храним ли мы 86400 записей об изменениях в день и доставляем их нашим клиентам? Что, если таких файлов сотни тысяч? Нам пришлось бы обрезать эти данные, и в этот момент потеря данных снижает то, насколько хорошо вы можете рассуждать об этом.
В конце концов, клиент очень редко делает что-то большее, чем пытается прочитать файл или просмотреть его метаданные, и, вообще говоря, он хочет делать это только тогда, когда файл перестал изменяться. Для этого варианта использования watchman-wait, watchman-make и trigger имеют концепцию периода согласования, который приводит к задержке доставки уведомлений об изменениях до тех пор, пока файловая система не перестанет изменяться.
person
Wez Furlong
schedule
02.03.2016