From 672dc74ec1d93da334aa7c3c003944f3695420dc Mon Sep 17 00:00:00 2001 From: rdavidek Date: Sun, 28 Dec 2025 21:08:56 +0100 Subject: [PATCH] data as TTL --- src/main/java/cz/kamma/darts/App.java | 34 ++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/cz/kamma/darts/App.java b/src/main/java/cz/kamma/darts/App.java index 45d509a..e68c0c0 100644 --- a/src/main/java/cz/kamma/darts/App.java +++ b/src/main/java/cz/kamma/darts/App.java @@ -12,12 +12,31 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class App { private static final Gson GSON = new Gson(); - private static final Map> GAMES_CACHE = Collections.synchronizedMap(new HashMap<>()); + private static final Map GAMES_CACHE = new ConcurrentHashMap<>(); private static final long MAX_UPLOAD_SIZE = 5 * 1024 * 1024; // 5MB + private static final long TTL_MS = TimeUnit.HOURS.toMillis(2); + + static class CachedData { + final List games; + final long expiryTime; + + CachedData(List games) { + this.games = games; + this.expiryTime = System.currentTimeMillis() + TTL_MS; + } + + boolean isExpired() { + return System.currentTimeMillis() > expiryTime; + } + } public static void main(String[] args) throws IOException { int port = 8080; @@ -28,6 +47,11 @@ public class App { server.createContext("/api/upload", new UploadHandler()); server.createContext("/api/clear", new ClearHandler()); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.scheduleAtFixedRate(() -> { + GAMES_CACHE.entrySet().removeIf(entry -> entry.getValue().isExpired()); + }, 1, 1, TimeUnit.MINUTES); + server.setExecutor(null); System.out.println("Server started on port " + port); server.start(); @@ -105,7 +129,7 @@ public class App { List convertedGames = convertRawToGames(rawGames); String code = generateCode(); - GAMES_CACHE.put(code, convertedGames); + GAMES_CACHE.put(code, new CachedData(convertedGames)); exchange.getResponseHeaders().set("Location", "/?code=" + code); exchange.sendResponseHeaders(303, -1); @@ -195,10 +219,8 @@ public class App { Map params = parseQuery(exchange.getRequestURI().getQuery()); String code = params.get("code"); - List games = (code != null) ? GAMES_CACHE.get(code.toUpperCase()) : null; - if (games == null) { - games = Collections.emptyList(); - } + CachedData cached = (code != null) ? GAMES_CACHE.get(code.toUpperCase()) : null; + List games = (cached != null && !cached.isExpired()) ? cached.games : Collections.emptyList(); StatsResponse response = aggregateStats(new ArrayList<>(games));