You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于数组与Mutex的Ruby简易限流算法完善咨询

Refining Your Array-Based Rate Limiter (5 Requests / 5 Minutes)

Nice approach starting with an array for timestamps and a Mutex for thread safety—let's polish this up to make it more efficient, maintainable, and scalable for real-world use. Here are key optimizations and a revised implementation:

Core Optimizations to Address

1. Prevent Unbounded Array Growth

Your initial setup will keep adding timestamps forever, which eats up memory over time. The fix? Clean up expired timestamps on every check before evaluating the current request count. Since timestamps are added in chronological order, we can quickly filter out anything older than the 5-minute window.

2. Speed Up Expired Timestamp Removal

Instead of looping through the entire array to find expired entries, leverage the sorted nature of the timestamp array. Use a binary search to find the first timestamp that's still within the allowed window—all entries before that index are expired and can be sliced off in one go. This reduces the operation from O(n) to O(log n) time.

3. Make the Limiter Configurable & Reusable

Hardcoding "5 minutes" and "5 requests" limits flexibility. Wrap the logic in a class where these parameters are configurable, so you can reuse it for different rate-limiting rules.

Revised Implementation (Ruby Example)

class ArrayRateLimiter
  def initialize(max_requests:, window_seconds:)
    @max_requests = max_requests
    @window_seconds = window_seconds
    @timestamps = []
    @mutex = Mutex.new
  end

  def allow_request?
    @mutex.synchronize do
      # Step 1: Clean up expired timestamps
      current_time = Time.now.to_i
      cutoff_time = current_time - @window_seconds

      # Use binary search to find the first valid timestamp index
      first_valid_idx = @timestamps.bsearch_index { |ts| ts >= cutoff_time } || 0
      @timestamps = @timestamps[first_valid_idx..-1] || []

      # Step 2: Check if we're under the request limit
      if @timestamps.length < @max_requests
        @timestamps << current_time
        true
      else
        false
      end
    end
  end
end

# Usage example: 5 requests allowed in 5 minutes (300 seconds)
limiter = ArrayRateLimiter.new(max_requests: 5, window_seconds: 300)

# Simulate API calls
10.times do |i|
  puts "Request #{i+1}: #{limiter.allow_request? ? 'Allowed' : 'Blocked'}"
  sleep(60) # Wait 1 minute between requests to test the window
end

Key Details Explained

  • Mutex Synchronization: The synchronize block ensures that only one thread can modify or read the @timestamps array at a time, eliminating race conditions.
  • Binary Search Cleanup: bsearch_index quickly finds the first timestamp that's still within the window, so we don't waste time checking every expired entry.
  • Configurable Parameters: The class accepts max_requests and window_seconds, making it easy to adapt to different rate limits (e.g., 10 requests per minute, 100 requests per hour).

Additional Considerations

  • Distributed Systems: If you need rate limiting across multiple servers, an in-memory array won't work—you'll need a shared store like Redis with sorted sets to track timestamps across instances.
  • Edge Cases: For very high request volumes, even an optimized array might have performance limits. In that case, consider using a fixed-size circular buffer or a sliding window counter approach.

内容的提问来源于stack exchange,提问作者theGreenCabbage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:39:13