Как решить проблему с прерыванием события в FSEventStream

Наше приложение C ++ использует FSEventStream для мониторинга файловой системы с гранулярностью на уровне файлов (создание потока с флагом kFSEventStreamCreateFlagFileEvents) с одним прослушивателем на каждый том. Однако в API Apple FSEvent, похоже, есть некоторые ошибки / ошибки, связанные с тем, как они сжимают (удаляют дубликаты) события из потока перед его отправкой нам:

  1. Незначительно, но раздражает: при запуске потока с использованием предыдущего идентификатора события в качестве отправной точки (для регистрации изменений в файловой системе со времени последнего мониторинга) порядок предоставляемых событий отличается от того, который мы получаем, если мы слушаем события по мере их возникновения, в том смысле, что они поступают не в порядке eventId, а сортируются в алфавитном порядке по имени файла. Мы решили эту проблему, накапливая все исторические события в списке, отсортированном по идентификатору, перед обработкой набора.

  2. Major: Если события переименования происходят достаточно быстро, фактические события, передаваемые нам в функции обратного вызова, не отражают того, что фактически произошло в файловой системе. Рассмотрим наш тестовый пример, в котором мы меняем имена каталогов:

    а. изменить файл

    б. переименуйте его родительский каталог в _temp

    с. переименовать другой каталог в имя предыдущего родителя

    д. переименуйте _temp в dir на шаге c.

Если мы поместим задержку в 50 мс между каждым из этих шагов (по существу, любая задержка, которая гарантирует, что данное событие не будет в том же обратном вызове, что и другое событие), мы получим правильную последовательность событий (с переименованиями, отображаемыми в виде пар событий):

fsEventsCallback: Received FSEvents callback with 1 events:
fsEventsCallback: ID=34303406 PATH= /Users/stebro/swaptest/subdir1/file_1.txt FLAGS=kFSEventStreamEventFlagItemInodeMetaMod, kFSEventStreamEventFlagItemIsFile, kFSEventStreamEventFlagItemModified
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303436 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303437 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303620 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303621 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: Received FSEvents callback with 2 events:
fsEventsCallback: ID=34303741 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34303742 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed

Однако без задержки (или настолько малой задержки, что множественные события переименования будут поступать при одном и том же вызове обратного вызова), создается впечатление, что ОС использует «услугу» удаления того, что она считает избыточными событиями, что приводит к этому беспорядку. :

fsEventsCallback: Received FSEvents callback with 4 events:
fsEventsCallback: ID=34251572 PATH= /Users/stebro/swaptest/subdir1/file_1.txt FLAGS=kFSEventStreamEventFlagItemInodeMetaMod, kFSEventStreamEventFlagItemIsFile, kFSEventStreamEventFlagItemModified
fsEventsCallback: ID=34251580 PATH= /Users/stebro/swaptest/subdir1 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34251583 PATH= /Users/stebro/swaptest/subdir1_temp FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed
fsEventsCallback: ID=34251584 PATH= /Users/stebro/swaptest/subdir2 FLAGS=kFSEventStreamEventFlagItemIsDir, kFSEventStreamEventFlagItemRenamed

Есть ли что-то, что мы можем сделать, чтобы подавить это сжатие? Мы создаем поток с помощью этого вызова:

FSEventStreamCreateRelativeToDevice(kCFAllocatorDefault,
&fsEventsCallback,
&context,
device,
reinterpret_cast<CFArrayRef>(_monitoredPaths),
lastEventId,
0, // Latency - problem exists with values of 1, 0.1 and 3 as well
kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer);

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]