Файлы, прочитанные сразу после уведомления сторожа, пусты
Я интегрирую watchman через интерфейс socket/bser в программу JVM.
Я вижу странное время, когда:
- Файл записывается системой сборки (небольшой текстовый файл)
- Я получаю уведомление сторожа на интерфейсе bser
- Поток Прослушивание уведомлений о подписке bser помещает обновление в очередь для отдельного потока.
- Поток B читает очередь, читает измененный файл и затем помещает данные файла в провод
Тем не менее, каким-то образом поток B читает пустой файл.
Который, я полагаю, в какой-то момент действительно пуст, например, IO/ системные вызовы могут быть:
- Очистить содержимое файла
- Написать кусок 1
- Написать кусок 2
- Закройте файл
И я предполагаю, что мой поток B читает файл между шагами 1 и 2. Или, может быть, 1 и 4, если 4 - когда результат сбрасывается.
Моя путаница состоит из двух частей:
1) Я думал, что ожидание сторожа по умолчанию в 20 мс будет учитывать такие вещи, и я буду видеть только обновление в моем потоке A, не говоря уже о том, что мой поток B выполняет чтение, после шага 4, и данные уже записаны в файл.
2) Даже если сторож сказал мне "слишком рано" о 1-м системном вызове (скажем, шаг 1), и я прочитал результаты, пока он был пустым файлом, должно появиться другое уведомление syscall/watchman о том, что "между прочим, файл имеет некоторое содержание сейчас ".
FWIW/oddly enough, I was seeing this very same behavior when using the Java WatchService API, where I would get an inotify event, but read a file "too soon", and so get either empty or partial results, and then no follow up inotify event when the rest of the data was available.
I assumed this was a fluke/nuance of the WatchService, so I solved it at the time by checking the file mod time before reading it, and just waiting to ensure mod time >2 seconds old before assuming the file is "done" being written.
(Note that this also handled ~100mb+ files being written, where the build process might write a chunk of data every 100ms+, but with WatchService I was seeing 100s of inotify notifications for what was essentially a single continuous write.)
When I ported my WatchService code to watchman, I dropped this "ensureSettled" hack, because I assumed watchman's 20ms settle period (which is way lower than the 2s I was using, but hey it's the default) + it's general robustness compared to the somewhat beta WatchService would mean it wouldn't be a problem.
But within ~a day of using the watchman-ported code, I'm seeing empty file reads, just like I was with the WatchService.
Any ideas about what I'm missing?
I can add back the ensureSettled hack, but at this point I'm curious about what is going on.
1 ответ
Документы не очень ясно об этом, извините!
На отправку уведомлений о подписке устанавливается тайм-аут расчета, но, поскольку обновления файлов не являются атомарными, вполне вероятно, что значение по умолчанию составляет 20 мсек, прежде чем содержимое файла станет видимым для вас; под прикрытием ядро генерирует серию уведомлений о различных мутациях, которые вы делаете, поэтому, если усечение занимает 20 мс, прежде чем вы записываете (или, возможно, сбрасываете) данные, вы, скорее всего, получите уведомление "посередине" ".
Этот материал также зависит от операционной системы. Вот пример недавно обнаруженной и решенной проблемы: https://github.com/facebook/watchman/commit/bac383c751b248ae742a2a20df3e8272238c0ae2 это не похоже на то, что вы испытываете, просто добавляет немного цвета это обсуждение.
Если у вас уже есть код для управления расчетами в вашем клиенте, вам будет проще добавить его обратно; мы делаем это в watchman-make
например. Вы также можете попробовать установить https://facebook.github.io/watchman/docs/config.html в .watchmanconfig
файл в корне дерева каталогов, которое вы смотрите, и оставьте его серверу сторожа. Если / когда вы измените этот параметр, вам нужно будет удалить и перезапустить часы.
То, что вы выберете, зависит от того, как вы хотите сопоставить простоту конфигурации с объемом кода, который вы хотите поддерживать, и (возможно) с объемом вопросов поддержки от вашей пользовательской базы, если .watchmanconfig
неправильно настроен для них.
Обратите внимание, что вы можете использовать вызов команды из https://facebook.github.io/watchman/docs/cmd/log-level.html чтобы просмотреть журнал отладки для уведомлений ядра по мере их поступления в режиме реального времени; это может помочь вам понять, какие именно уведомления приходят и когда.
Просто любопытно, используете ли вы https://github.com/facebook/watchman/tree/master/java для общения с сервером сторожа?