To achieve the requirements of logging image uploads in Redis and ensuring that a user does not upload more than 20 images in one hour and not more than 200 images in one day, you can use Redis' sorted sets (zsets) to store timestamps of uploads. This will allow you to efficiently query and count uploads within specific time ranges.
Here's a step-by-step solution:
-
Store Upload Timestamps in Redis:
- Use a sorted set to store the timestamps of each upload. The score of each entry in the sorted set will be the timestamp of the upload.
-
Check Upload Limits:
- Before allowing an upload, check the number of uploads in the past hour and the past day using the
ZCOUNTcommand.
- Before allowing an upload, check the number of uploads in the past hour and the past day using the
-
Add New Uploads:
- After verifying the limits, add the new upload timestamp to the sorted set.
-
Clean Up Old Entries:
- Optionally, you can periodically clean up old entries to keep the Redis storage efficient.
Here is a code example in Laravel using the Redis facade:
use Illuminate\Support\Facades\Redis;
function canUpload($userId) {
$currentTime = time();
$oneHourAgo = $currentTime - 3600;
$oneDayAgo = $currentTime - 86400;
// Check uploads in the last hour
$uploadsLastHour = Redis::zcount("user:{$userId}:uploads", $oneHourAgo, $currentTime);
if ($uploadsLastHour >= 20) {
return false; // Exceeded hourly limit
}
// Check uploads in the last day
$uploadsLastDay = Redis::zcount("user:{$userId}:uploads", $oneDayAgo, $currentTime);
if ($uploadsLastDay >= 200) {
return false; // Exceeded daily limit
}
return true; // Allowed to upload
}
function logUpload($userId, $imageName) {
$currentTime = time();
// Add the upload timestamp to the sorted set
Redis::zadd("user:{$userId}:uploads", $currentTime, $imageName);
// Optionally, clean up old entries (older than one day)
$oneDayAgo = $currentTime - 86400;
Redis::zremrangebyscore("user:{$userId}:uploads", 0, $oneDayAgo);
}
// Example usage
$userId = 1;
$imageName = 'example.jpg';
if (canUpload($userId)) {
logUpload($userId, $imageName);
echo "Upload successful!";
} else {
echo "Upload limit exceeded!";
}
Explanation:
-
canUpload Function:
- This function checks if the user can upload an image by counting the number of uploads in the last hour and the last day using
zcount.
- This function checks if the user can upload an image by counting the number of uploads in the last hour and the last day using
-
logUpload Function:
- This function logs the upload by adding the current timestamp and image name to the sorted set using
zadd. - It also removes entries older than one day using
zremrangebyscoreto keep the sorted set clean.
- This function logs the upload by adding the current timestamp and image name to the sorted set using
Redis Key Structure:
-
user:{userId}:uploads: A sorted set where the score is the timestamp of the upload and the value is the image name.
This approach ensures that you can efficiently check and enforce the upload limits using Redis' sorted set operations.