waitForPermission method

Future<void> waitForPermission(
  1. String domain
)

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;
}