Как правильно обрабатывать тип переполнения pollEvents() в службе часов?

Я использую службу наблюдения для мониторинга каталога и запуска логики во вновь созданных файлах. Одна из проблем, с которой я недавно столкнулся, — это переполнение, которое возникает, когда необходимо обработать большой объем файлов, и они слишком быстро копируются в каталог просмотра.

В API говорится о переполнении:

Файловые системы могут сообщать о событиях быстрее, чем они могут быть извлечены или обработаны, и реализация может наложить неуказанный предел на количество событий, которые она может накапливать. Если реализация намеренно отбрасывает события, то метод pollEvents ключа возвращает элемент с типом события OVERFLOW.

Мой вопрос в том, как я могу правильно обрабатывать переполнение, не теряя ни одного из событий, которые необходимо обработать?

Мой код службы часов выглядит так:

            Path myDir = Paths.get(srcDir);
            try(WatchService watcher = myDir.getFileSystem().newWatchService()){
                myDir.register(watcher, ENTRY_CREATE,ENTRY_MODIFY);
                int x = 0;
                for(;;){
                    x++;
                    WatchKey watchKey = watcher.take();
                    LOGGER.debug("Event # {}",x);
                    List<WatchEvent<?>> events = watchKey.pollEvents();
                    LOGGER.info("Events Size {}",events.size());
                    for (WatchEvent event : events) {
                        if(event.kind() == OVERFLOW){
                            LOGGER.error("The Maximum watchService events has been reached!");
                            System.exit(1); //I exit so I know there is a problem - but how should I handle this? 
                        }
                        if (event.kind() == ENTRY_CREATE) {
                            LOGGER.info("File created: " + event.context().toString());
                            LOGGER.info("Beginning Processing:" +event.context().toString());
                            ...business logic here...
                        }
                    }
                    watchKey.reset();
                }
          ...

person Robert H    schedule 29.07.2013    source источник
comment
Переполнение означает, что вы потеряли события. Нет смысла говорить, что вы хотите обработать переполнение и не потерять события.   -  person Peter Lawrey    schedule 29.07.2013
comment
@PeterLawrey В документации также указано This event can be used by the consumer as a trigger to re-examine the state of the object. Если я потеряю событие из-за переполнения, будут ли мои следующие события стоять в очереди? и если да, то как мне получить следующий набор событий?   -  person Robert H    schedule 29.07.2013


Ответы (1)


Я никогда не видел события переполнения на практике. Он предназначен для того, чтобы сообщить вам, что вам нужно будет повторно обработать любой каталог, который вы просматриваете. Вам не нужно выходить из программы, просто просмотрите каталог, используя однопоточный вызов File.list(). Ниже я вырезал и вставил, как я с этим справляюсь. Этот код...

1) Регистрирует проблему

2) Устанавливает флаг для запуска повторной обработки каталога, которая сканирует все файлы в каталоге.

3) Пропускает остальную часть обработки этого WatchEvent

// log overflow events and trigger reprocess later.
if (kind == OVERFLOW) 
{
    logger.warn("File listener recieved an overflow event.  You should probably check into this");
    overflowTriggeredFlag = true;
    continue;
}
person sevensevens    schedule 29.07.2013