aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-11-27 11:14:15 -0800
committerAnton Tananaev <anton@traccar.org>2022-11-27 11:14:15 -0800
commit20ca33bf17c30bf2335d85365a224bc437e0347b (patch)
tree80b57985f09dd898d4cfdaab6c3726d08efea9d8
parent146de22b51139edcc3132f403e86006ac1fc3419 (diff)
downloadtrackermap-server-20ca33bf17c30bf2335d85365a224bc437e0347b.tar.gz
trackermap-server-20ca33bf17c30bf2335d85365a224bc437e0347b.tar.bz2
trackermap-server-20ca33bf17c30bf2335d85365a224bc437e0347b.zip
Unknown device throttling
-rw-r--r--src/main/java/org/traccar/config/Keys.java9
-rw-r--r--src/main/java/org/traccar/database/DeviceLookupService.java47
2 files changed, 38 insertions, 18 deletions
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<Boolean> 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<Boolean> 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<String, IdentifierInfo> 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) {