mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-14 08:41:28 +00:00
fix threading issue in notification manager
Signed-off-by: Armin Schrenk <armin.schrenk@skymatic.de>
This commit is contained in:
@@ -266,7 +266,7 @@ public class Vault {
|
||||
|
||||
private void consumeVaultEvent(FilesystemEvent e) {
|
||||
fileSystemEventAggregator.put(this, e);
|
||||
notificationManager.tryAddEvent(this, e);
|
||||
notificationManager.offer(this, e);
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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
|
||||
* <li>
|
||||
* <ul>the event should trigger a notification and</ul>
|
||||
* <ul>it is not added within the last {@value DEBOUNCE_THRESHOLD_SECONDS} seconds</ul>
|
||||
* </li>
|
||||
* <ul>
|
||||
* <li>the event should trigger a notification and</li>
|
||||
* <li>it is not added within the last {@value DEBOUNCE_THRESHOLD_SECONDS} seconds</li>
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
@@ -30,31 +28,38 @@ public class NotificationManager {
|
||||
|
||||
private static final int DEBOUNCE_THRESHOLD_SECONDS = 5;
|
||||
|
||||
Cache<Path, FilesystemEvent> eventCache;
|
||||
Queue<VaultEvent> eventsRequiringNotification;
|
||||
Cache<FSEventBucket, FilesystemEvent> eventCache;
|
||||
ConcurrentLinkedQueue<VaultEvent> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user