From 20ca33bf17c30bf2335d85365a224bc437e0347b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Nov 2022 11:14:15 -0800 Subject: Unknown device throttling --- src/main/java/org/traccar/config/Keys.java | 9 ++++- .../org/traccar/database/DeviceLookupService.java | 47 ++++++++++++++-------- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 9ae71921e..09662fc85 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -452,7 +452,14 @@ public final class Keys { List.of(KeyType.CONFIG)); /** - * By default server syncs with the database if it encounters and unknown device. This flag allows to disable that + * Throttle unknown device database queries when it sends repeated requests. + */ + public static final ConfigKey DATABASE_THROTTLE_UNKNOWN = new BooleanConfigKey( + "database.throttleUnknown", + List.of(KeyType.CONFIG)); + + /** + * By default, server syncs with the database if it encounters and unknown device. This flag allows to disable that * behavior to improve performance in some cases. */ public static final ConfigKey DATABASE_IGNORE_UNKNOWN = new BooleanConfigKey( diff --git a/src/main/java/org/traccar/database/DeviceLookupService.java b/src/main/java/org/traccar/database/DeviceLookupService.java index 28910c24a..583b2ae35 100644 --- a/src/main/java/org/traccar/database/DeviceLookupService.java +++ b/src/main/java/org/traccar/database/DeviceLookupService.java @@ -20,6 +20,8 @@ import io.netty.util.Timer; import io.netty.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.model.Device; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; @@ -45,6 +47,8 @@ public class DeviceLookupService { private final Storage storage; private final Timer timer; + private final boolean throttlingEnabled; + private static class IdentifierInfo { private long lastQuery; private long delay; @@ -70,36 +74,45 @@ public class DeviceLookupService { private final Map identifierMap = new ConcurrentHashMap<>(); @Inject - public DeviceLookupService(Storage storage, Timer timer) { + public DeviceLookupService(Config config, Storage storage, Timer timer) { this.storage = storage; this.timer = timer; + throttlingEnabled = config.getBoolean(Keys.DATABASE_THROTTLE_UNKNOWN); } private synchronized boolean isThrottled(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + return info != null && System.currentTimeMillis() < info.lastQuery + info.delay; + } else { + return false; + } } private synchronized void lookupSucceeded(String uniqueId) { - IdentifierInfo info = identifierMap.remove(uniqueId); - if (info != null) { - info.timeout.cancel(); + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.remove(uniqueId); + if (info != null) { + info.timeout.cancel(); + } } } private synchronized void lookupFailed(String uniqueId) { - IdentifierInfo info = identifierMap.get(uniqueId); - if (info != null) { - info.timeout.cancel(); - info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); - } else { - info = new IdentifierInfo(); - identifierMap.put(uniqueId, info); - info.delay = THROTTLE_MIN_MS; + if (throttlingEnabled) { + IdentifierInfo info = identifierMap.get(uniqueId); + if (info != null) { + info.timeout.cancel(); + info.delay = Math.min(info.delay * 2, THROTTLE_MAX_MS); + } else { + info = new IdentifierInfo(); + identifierMap.put(uniqueId, info); + info.delay = THROTTLE_MIN_MS; + } + info.lastQuery = System.currentTimeMillis(); + info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); + LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } - info.lastQuery = System.currentTimeMillis(); - info.timeout = timer.newTimeout(new IdentifierTask(uniqueId), INFO_TIMEOUT_MS, TimeUnit.MILLISECONDS); - LOGGER.debug("Device lookup {} throttled for {} ms", uniqueId, info.delay); } public Device lookup(String[] uniqueIds) { -- cgit v1.2.3