Class: A2A::Client::Middleware::RateLimitInterceptor

Inherits:
Object
  • Object
show all
Defined in:
lib/a2a/client/middleware/rate_limit_interceptor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(requests_per_second: 10, burst_size: 20) ⇒ RateLimitInterceptor

Initialize rate limit interceptor

Parameters:

  • (defaults to: 10)

    Maximum requests per second (default: 10)

  • (defaults to: 20)

    Maximum burst size (default: 20)



20
21
22
23
24
25
26
27
28
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 20

def initialize(requests_per_second: 10, burst_size: 20)
  @requests_per_second = requests_per_second.to_f
  @burst_size = burst_size
  @tokens = @burst_size.to_f
  @last_refill = Time.now
  @mutex = Mutex.new

  validate_configuration!
end

Instance Attribute Details

#burst_sizeObject (readonly)

Returns the value of attribute burst_size.



13
14
15
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 13

def burst_size
  @burst_size
end

#last_refillObject (readonly)

Returns the value of attribute last_refill.



13
14
15
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 13

def last_refill
  @last_refill
end

#requests_per_secondObject (readonly)

Returns the value of attribute requests_per_second.



13
14
15
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 13

def requests_per_second
  @requests_per_second
end

#tokensObject (readonly)

Returns the value of attribute tokens.



13
14
15
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 13

def tokens
  @tokens
end

Instance Method Details

#call(request, context, next_middleware) ⇒ Object

Execute request with rate limiting

Parameters:

  • The request object

  • Request context

  • Next middleware in chain

Returns:

  • Response from next middleware



37
38
39
40
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 37

def call(request, context, next_middleware)
  wait_for_token
  next_middleware.call(request, context)
end

#can_make_request?Boolean

Check if a request can be made immediately

Returns:

  • True if request can be made without waiting



46
47
48
49
50
51
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 46

def can_make_request?
  @mutex.synchronize do
    refill_tokens
    @tokens >= 1.0
  end
end

#refill_tokensObject (private)

Refill tokens based on elapsed time



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 116

def refill_tokens
  now = Time.now
  elapsed = now - @last_refill

  return unless elapsed.positive?

  # Add tokens based on elapsed time
  tokens_to_add = elapsed * @requests_per_second
  @tokens = [@tokens + tokens_to_add, @burst_size].min
  @last_refill = now
end

#reset!Object

Reset the rate limiter (useful for testing)



86
87
88
89
90
91
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 86

def reset!
  @mutex.synchronize do
    @tokens = @burst_size.to_f
    @last_refill = Time.now
  end
end

#statusHash

Get current rate limit status

Returns:

  • Rate limit status information



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 57

def status
  @mutex.synchronize do
    refill_tokens
    {
      requests_per_second: @requests_per_second,
      burst_size: @burst_size,
      available_tokens: @tokens.round(2),
      tokens_full: @tokens >= @burst_size,
      can_make_request: @tokens >= 1.0
    }
  end
end

#time_until_next_tokenFloat

Calculate time until next token is available

Returns:

  • Time in seconds until next token



74
75
76
77
78
79
80
81
82
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 74

def time_until_next_token
  @mutex.synchronize do
    refill_tokens
    return 0.0 if @tokens >= 1.0

    tokens_needed = 1.0 - @tokens
    tokens_needed / @requests_per_second
  end
end

#validate_configuration!Object (private)

Validate configuration parameters

Raises:



130
131
132
133
134
135
136
137
138
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 130

def validate_configuration!
  raise ArgumentError, "requests_per_second must be positive" if @requests_per_second <= 0

  raise ArgumentError, "burst_size must be positive" if @burst_size <= 0

  return unless @burst_size < @requests_per_second

  warn "Warning: burst_size (#{@burst_size}) is less than requests_per_second (#{@requests_per_second})"
end

#wait_for_tokenObject (private)

Wait for a token to become available



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/a2a/client/middleware/rate_limit_interceptor.rb', line 97

def wait_for_token
  loop do
    @mutex.synchronize do
      refill_tokens

      if @tokens >= 1.0
        @tokens -= 1.0
        return
      end
    end

    # Calculate how long to sleep
    sleep_time = time_until_next_token
    sleep(sleep_time) if sleep_time.positive?
  end
end