From d3538bde39b15534c2623b40bef0230552e1005e Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Sat, 25 May 2019 22:16:04 +0100 Subject: [PATCH] check for duplicate search UUIDs, cleanup old ones --- .../muwire/core/search/SearchManager.groovy | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/search/SearchManager.groovy b/core/src/main/groovy/com/muwire/core/search/SearchManager.groovy index 11886f05..11806812 100644 --- a/core/src/main/groovy/com/muwire/core/search/SearchManager.groovy +++ b/core/src/main/groovy/com/muwire/core/search/SearchManager.groovy @@ -9,10 +9,13 @@ import net.i2p.data.Destination @Log public class SearchManager { + private static final int EXPIRE_TIME = 60 * 1000 * 1000 + private static final int CHECK_INTERVAL = 60 * 1000 + private final EventBus eventBus private final Persona me private final ResultsSender resultsSender - private final Map responderAddress = new HashMap<>() + private final Map responderAddress = Collections.synchronizedMap(new HashMap<>()) SearchManager(){} @@ -20,16 +23,21 @@ public class SearchManager { this.eventBus = eventBus this.me = me this.resultsSender = resultsSender + Timer timer = new Timer("query-expirer", true) + timer.schedule({cleanup()} as TimerTask, CHECK_INTERVAL, CHECK_INTERVAL) } void onQueryEvent(QueryEvent event) { - // TODO: duplicate UUID check - responderAddress.put(event.searchEvent.uuid, event.replyTo) + if (responderAddress.containsKey(event.searchEvent.uuid)) { + log.info("Dropping duplicate search uuid $event.searchEvent.uuid") + return + } + responderAddress.put(event.searchEvent.uuid, event) eventBus.publish(event.searchEvent) } void onResultsEvent(ResultsEvent event) { - Destination target = responderAddress.get(event.uuid) + Destination target = responderAddress.get(event.uuid)?.replyTo if (target == null) throw new IllegalStateException("UUID unknown $event.uuid") if (event.results.length == 0) { @@ -40,6 +48,18 @@ public class SearchManager { } boolean hasLocalSearch(UUID uuid) { - me.destination.equals(responderAddress.get(uuid)) + me.destination.equals(responderAddress.get(uuid)?.replyTo) + } + + private void cleanup() { + final long now = System.currentTimeMillis() + synchronized(responderAddress) { + for (Iterator iter = responderAddress.keySet().iterator(); iter.hasNext();) { + UUID uuid = iter.next() + QueryEvent event = responderAddress.get(uuid) + if (event.timestamp < now - EXPIRE_TIME) + iter.remove() + } + } } }