diff --git a/src/main/java/org/cryptomator/common/vaults/Vault.java b/src/main/java/org/cryptomator/common/vaults/Vault.java index 24418dc7e..974e79004 100644 --- a/src/main/java/org/cryptomator/common/vaults/Vault.java +++ b/src/main/java/org/cryptomator/common/vaults/Vault.java @@ -266,7 +266,7 @@ public class Vault { private void consumeVaultEvent(FilesystemEvent e) { fileSystemEventAggregator.put(this, e); - notificationManager.tryAddEvent(this, e); + notificationManager.offer(this, e); } // ****************************************************************************** diff --git a/src/main/java/org/cryptomator/event/NotificationManager.java b/src/main/java/org/cryptomator/event/NotificationManager.java index c2b0e4158..190d33df4 100644 --- a/src/main/java/org/cryptomator/event/NotificationManager.java +++ b/src/main/java/org/cryptomator/event/NotificationManager.java @@ -3,26 +3,24 @@ package org.cryptomator.event; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.cryptofs.event.BrokenFileNodeEvent; import org.cryptomator.cryptofs.event.FilesystemEvent; import javax.inject.Inject; import javax.inject.Singleton; import java.nio.file.Path; import java.time.Duration; -import java.util.ArrayDeque; import java.util.List; -import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Manager for notifications. *

- * To add (filesystem) events, use method {@link #tryAddEvent(Vault, FilesystemEvent)}. If the input event is eligible, it is added to an internal queue. + * To add (filesystem) events, use method {@link #offer(Vault, FilesystemEvent)}. If the input event is eligible, it is added to an internal queue. * An event is eligible, if - *

  • - * - * - *
  • + * * */ @Singleton @@ -30,31 +28,38 @@ public class NotificationManager { private static final int DEBOUNCE_THRESHOLD_SECONDS = 5; - Cache eventCache; - Queue eventsRequiringNotification; + Cache eventCache; + ConcurrentLinkedQueue eventsRequiringNotification; @Inject public NotificationManager() { eventCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(DEBOUNCE_THRESHOLD_SECONDS)).build(); - eventsRequiringNotification = new ArrayDeque<>(); + eventsRequiringNotification = new ConcurrentLinkedQueue<>(); } - - public boolean tryAddEvent(Vault v, FilesystemEvent e) { - var notRecentlyAdded = switch (e) { - case BrokenFileNodeEvent bfne -> isRecent(bfne.ciphertextPath(), bfne); + + /** + * Offers the given filesystem event to the notification manager. + * + * @param v The vault where the filesystem event happened + * @param e the actual filesystem event + * @return {@code true} if the filesystem event is accepted, otherwise {@code false}. + */ + public boolean offer(Vault v, FilesystemEvent e) { + return switch (e) { + //example: case BrokenFileNodeEvent bfne -> addEvent(v, bfne.ciphertextPath(), bfne); default -> false; }; - if (notRecentlyAdded) { + } + + boolean addEvent(Vault v, Path keyPath, FilesystemEvent e) { + var key = new FSEventBucket(v, keyPath, e.getClass()); + var cachedElement = eventCache.get(key, _ -> { synchronized (this) { eventsRequiringNotification.add(new VaultEvent(v, e)); } - } - return notRecentlyAdded; - } - - boolean isRecent(Path key, FilesystemEvent e) { - var cacheElement = eventCache.get(key, _ -> e); - return cacheElement == e; + return e; + }); + return cachedElement != e; } /**