waitForPermission method
Waits until a request can be made to the given domain
Implementation
Future<void> waitForPermission(String domain) async {
final now = DateTime.now();
// Initialize request timestamps if needed
_requestTimestampsPerMinute[domain] ??= Queue<DateTime>();
_requestTimestampsPerHour[domain] ??= Queue<DateTime>();
_requestTimestampsPerDay[domain] ??= Queue<DateTime>();
// Clean up old timestamps
_cleanupOldTimestamps(domain, now);
// Check if we're within rate limits
final minuteLimit = getRateLimitPerMinute(domain);
final hourLimit = getRateLimitPerHour(domain);
final dayLimit = getRateLimitPerDay(domain);
final minuteCount = _requestTimestampsPerMinute[domain]!.length;
final hourCount = _requestTimestampsPerHour[domain]!.length;
final dayCount = _requestTimestampsPerDay[domain]!.length;
if (minuteCount < minuteLimit &&
hourCount < hourLimit &&
dayCount < dayLimit) {
// We're within rate limits, so we can proceed immediately
_recordRequest(domain, now);
return;
}
// We need to wait for a slot to open up
logger?.info(
'Rate limit reached for $domain. Waiting for a slot to open up.',
);
// Calculate wait time
final waitTime = _calculateWaitTime(domain, now);
if (waitTime <= Duration.zero) {
// No need to wait
_recordRequest(domain, now);
return;
}
// Create a completer for this request
final completer = Completer<void>();
_pendingRequests[domain] ??= [];
_pendingRequests[domain]!.add(completer);
// Schedule processing of this request
Timer(waitTime, () {
_processNextRequest(domain);
});
// Wait for our turn
return completer.future;
}