2013-07-29 7 views
5

Ich verwende einen Überwachungsdienst, um eine Verzeichnis- und Feuerlogik auf neu erstellten Dateien zu überwachen. Eine der Herausforderungen, die ich in letzter Zeit erlebt habe, ist ein Überlauf, der ausgelöst wird, wenn eine große Menge an Dateien verarbeitet werden muss und zu schnell in das Überwachungsverzeichnis kopiert wird.Wie überwinde ich pollEvents() in einem Watchservice?

Die API sagt über Überlauf:

Dateisysteme können Ereignisse schneller berichten, als sie abgerufen oder verarbeitet werden können und eine Implementierung kann eine nicht näher bezeichnete Begrenzung für die Anzahl von Ereignissen verhängen, die es ansammeln können. Wenn eine Implementierung wissentlich Ereignisse verwirft, veranlasst sie, dass die pollEvents-Methode des Schlüssels ein Element mit dem Ereignistyp OVERFLOW zurückgibt.

Meine Frage ist, wie kann ich den Überlauf richtig behandeln, ohne irgendwelche der Ereignisse zu verlieren, die verarbeitet werden müssen?

Mein watchservice Code wie folgt aussieht:

  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(); 
       } 
      ... 
+1

Ein Überlauf * bedeutet * Sie haben Ereignisse verloren. Es macht keinen Sinn zu sagen, dass Sie mit einem Überlauf umgehen und keine Ereignisse verlieren wollen. –

+0

@PeterLawrey In der Dokumentation wird außerdem Folgendes angezeigt: "Dieses Ereignis kann vom Benutzer als Auslöser verwendet werden, um den Status des Objekts erneut zu überprüfen." Wenn ich aufgrund eines Überlaufs ein Ereignis verliere, mache meine nächste Ereigniswarteschlange noch? und wenn ja, wie bekomme ich die nächste Reihe von Ereignissen? –

Antwort

2

Ich habe noch nie das Überlaufereignis in der Praxis gesehen. Es soll Ihnen mitteilen, dass Sie das Verzeichnis, das Sie gerade anschauen, erneut verarbeiten müssen. Sie müssen das Programm nicht beenden, sondern das Verzeichnis nur mit einem einzigen File.list() - Aufruf durchsuchen. Ich habe cut-n-pasted wie ich damit umgehe. Dieser Code ...

1) protokolliert ein Problem

2) einen Flag Legt ein Verzeichnis reprocess auszulösen, das alle Dateien in einem Verzeichnis

3) überspringt den Rest der Verarbeitung diesen kriecht 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; 
}