<?php
class RequestThrottler {
private $queue = []; // Queue of requests
private $limit; // Maximum number of requests allowed
private $timeWindow; // Time window for the limit
private $lastTimestamp = 0; // Timestamp of the last request within the window
public function __construct(int $limit, int $timeWindow) {
$this->limit = $limit;
$this->timeWindow = $timeWindow;
}
/**
* Checks if a request is allowed based on the throttling rules.
*
* @return bool True if the request is allowed, false otherwise.
*/
public function isAllowed(): bool {
$currentTime = time();
// Remove requests older than the time window
$this->queue = array_filter($this->queue, function ($request) use ($currentTime, $this->timeWindow) {
return $currentTime - $request['timestamp'] < $this->timeWindow;
});
// Check if the queue is full
if (count($this->queue) >= $this->limit) {
return false; // Throttled
}
$this->queue[] = ['timestamp' => $currentTime]; // Add current request to queue
return true; // Allowed
}
/**
* Processes a request.
*
* @param callable $callback The function to execute for the request.
* @param array $data Optional data to pass to the callback.
* @return mixed The result of the callback, or null on failure.
* @throws Exception If the request is throttled.
*/
public function processRequest(callable $callback, array $data = []): mixed
{
if (!$this->isAllowed()) {
throw new Exception("Request throttled. Too many requests in a short period.");
}
try {
return $callback($data);
} catch (Exception $e) {
//Handle exceptions from the callback
error_log("Error processing request: " . $e->getMessage());
throw $e;
}
}
}
//Example Usage
/*
$throttler = new RequestThrottler(5, 60); // Allow 5 requests per minute
try {
for ($i = 0; $i < 10; $i++) {
$result = $throttler->processRequest(function ($data) use ($i) {
return "Request " . $i . " processed";
});
echo $result . "\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
*/
?>
Add your comment