Class: Rapidity::Share::Sender

Inherits:
Base
  • Object
show all
Defined in:
lib/rapidity/share/sender.rb

Constant Summary collapse

LUA_SCRIPTS =
[:acquire, :release_queue, :available_in]

Constants inherited from Base

Base::BASE_SCRIPTS, Base::DEFAULT_KEY_TTL

Instance Method Summary collapse

Methods inherited from Base

#build_limit, #delete, #get_name, #handle_response, #info, #list, #reset, #wrap_executed_script

Constructor Details

#initialize(*args, **kwargs) ⇒ Sender

Returns a new instance of Sender.



7
8
9
# File 'lib/rapidity/share/sender.rb', line 7

def initialize(*args, **kwargs)
  super(*args, **kwargs)
end

Instance Method Details

#acquire(list_limits_or_str, tokens: 1, ttl: @ttl) ⇒ OpenStruct

Note:

If any limit cannot provide the requested tokens, the entire operation fails

Attempts to acquire tokens from one or multiple rate limits

This method attempts to reserve the specified number of tokens from each limit in the provided list. The operation succeeds only if all limits have available tokens.

Parameters:

  • list_limits_or_str (Array<Limit>, Array<String>)

    array of limit objects or limit names

  • tokens (Integer) (defaults to: 1)

    number of tokens to acquire from each limit

  • ttl (Integer) (defaults to: @ttl)

    time-to-live for the acquisition operation

Returns:

  • (OpenStruct)

    result of the acquisition attempt

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rapidity/share/sender.rb', line 22

def acquire(list_limits_or_str, tokens: 1, ttl: @ttl)
  list_limits_or_str = [list_limits_or_str] unless list_limits_or_str.is_a?(Array)
  
  raise ArgumentError, "limits list is empty" if list_limits_or_str.empty?
  raise ArgumentError, "tokens must be positive" unless tokens > 0

  limits = if list_limits_or_str[0].is_a?(Limit)
    list_limits_or_str.map {|it| it.name}
  else
    list_limits_or_str
  end

  response = wrap_executed_script do |r|
    r.evalsha(@lua_acquire, keys: [*limits], argv: [tokens, ttl])
  end

  handle_response(response)
end

#available_in(list_limits_or_str, tokens: 1, ttl: @ttl) ⇒ OpenStruct

Note:

Returns the maximum wait time among all limits (bottleneck)

Checks when tokens will be available in one or multiple rate limits

Calculates the maximum time until the specified number of tokens will be available across all provided limits.

Parameters:

  • list_limits_or_str (Array<Limit>, Array<String>)

    array of limit objects or limit names

  • tokens (Integer) (defaults to: 1)

    number of tokens to check availability for

  • ttl (Integer) (defaults to: @ttl)

    time-to-live parameter for the check

Returns:

  • (OpenStruct)

    availability information including wait times

Raises:

  • (ArgumentError)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rapidity/share/sender.rb', line 51

def available_in(list_limits_or_str, tokens: 1, ttl: @ttl)
  raise ArgumentError, "limits list is empty" if list_limits_or_str.empty?
  raise ArgumentError, "tokens must be positive" unless tokens > 0

  limits = if list_limits_or_str[0].is_a?(Limit)
    list_limits_or_str.map {|it| it.name}
  else
    list_limits_or_str
  end

  response = wrap_executed_script do |r|
    r.evalsha(@lua_available_in, keys: [*limits], argv: [tokens, ttl])
  end

  handle_response(response)
end

#release_queue(list_limits_or_str, count: 1, ttl: @ttl) ⇒ OpenStruct

Releases tokens back to the limit semaphore for ‘Feedback-Driven Flow Control`

Returns previously acquired tokens to the semaphore, making them available for generetor.

Parameters:

  • list_limits_or_str (Array<Limit>, Array<String>)

    array of limit objects or limit names

  • count (Integer) (defaults to: 1)

    number of tokens to release

  • ttl (Integer) (defaults to: @ttl)

    time-to-live for the released tokens

Returns:

  • (OpenStruct)

    result of the release operation

Raises:

  • (ArgumentError)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rapidity/share/sender.rb', line 77

def release_queue(list_limits_or_str, count: 1, ttl: @ttl)
  list_limits_or_str = [list_limits_or_str] unless list_limits_or_str.is_a?(Array)
  
  raise ArgumentError, "limits list is empty" if list_limits_or_str.empty?
  raise ArgumentError, "count must be positive" unless count > 0

  limits = if list_limits_or_str[0].is_a?(Limit)
    list_limits_or_str.map {|it| it.name}
  else
    list_limits_or_str
  end

  response = wrap_executed_script do |r|
    r.evalsha(@lua_release_queue, keys: [*limits], argv: [count, ttl])
  end

  handle_response(response)
end