import java.util.*;
import java.util.concurrent.*;
import java.time.Instant;
class TimestampMonitor {
private final int maxRequestsPerWindow;
private final long windowDurationMillis;
private final Map<String, List<Instant>> requestTimestamps; // Key: identifier, Value: List of timestamps
private final Map<String, BlockingQueue<Instant>> requestQueue; // Queue of requests for each identifier
private final ExecutorService rateLimiter;
public TimestampMonitor(int maxRequestsPerWindow, long windowDurationMillis) {
this.maxRequestsPerWindow = maxRequestsPerWindow;
this.windowDurationMillis = windowDurationMillis;
this.requestTimestamps = new HashMap<>();
this.requestQueue = new HashMap<>();
this.rateLimiter = Executors.newFixedThreadPool(10); //Adjust thread pool size as needed
}
public synchronized boolean allowRequest(String identifier) {
// Get the current time
Instant now = Instant.now();
// Get timestamps for the identifier
List<Instant> timestamps = requestTimestamps.getOrDefault(identifier, new ArrayList<>());
// Remove timestamps older than the window duration
timestamps.removeIf(ts -> now.minusMillis(windowDurationMillis).isBefore(ts));
// Check if the number of requests within the window exceeds the limit
if (timestamps.size() >= maxRequestsPerWindow) {
return false; // Rate limit exceeded
}
// Add the current timestamp to the list
timestamps.add(now);
requestTimestamps.put(identifier, timestamps);
// Add the timestamp to the queue
requestQueue.computeIfAbsent(identifier, k -> new LinkedBlockingQueue<>()).offer(now);
return true; // Request allowed
}
public void processQueue(String identifier) {
//Process requests from the queue for a given identifier
BlockingQueue<Instant> queue = requestQueue.get(identifier);
while (!queue.isEmpty()) {
Instant timestamp = queue.poll();
//Simulate processing the request with the timestamp
System.out.println("Processing request from " + identifier + " at: " + timestamp);
rateLimiter.submit(() -> {
try {
Thread.sleep(100); // Simulate processing time
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
}
public void shutdown() {
rateLimiter.shutdown();
try {
rateLimiter.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Add your comment