rapidity 0.0.7.369741 → 0.0.8.373806
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rapidity/share/base.rb +38 -5
- data/lib/rapidity/share/lua_scripts/acquire.lua +2 -2
- data/lib/rapidity/share/lua_scripts/acquire_queue.lua +3 -2
- data/lib/rapidity/share/lua_scripts/available_in.lua +3 -2
- data/lib/rapidity/share/lua_scripts/check_queue.lua +3 -2
- data/lib/rapidity/share/lua_scripts/info.lua +4 -3
- data/lib/rapidity/share/lua_scripts/init.lua +4 -3
- data/lib/rapidity/share/lua_scripts/release_queue.lua +3 -2
- data/lib/rapidity/share/lua_scripts/reset.lua +3 -2
- data/lib/rapidity/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed5172220150b7969f1df9030b0c721529017407dbc829f3421634fa91bcd2c0
|
|
4
|
+
data.tar.gz: 768ac1fff03adf7c186011bde86d25ec07f7f032b81794c1fe56f8c778304120
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 11fdd966c10b8e6202255e1c1f992239066d6593d6b0eab2d81b4d7a1179688272cb1e661a6318e1f4291c410d40b93d56bc270042cdc12ece1604ea7fe1dc57
|
|
7
|
+
data.tar.gz: aef378f5b068cbcef69b5188314b253908a61d1cf1056d1e036609ad3b510b69aab0cb8f9bd450dfed706cd122eaa1725164f1c7a3651001537e363a4e6eb1d0
|
data/Gemfile.lock
CHANGED
data/lib/rapidity/share/base.rb
CHANGED
|
@@ -8,12 +8,15 @@ module Rapidity
|
|
|
8
8
|
BASE_SCRIPTS = [:list, :info, :reset, :delete]
|
|
9
9
|
DEFAULT_KEY_TTL = 6000
|
|
10
10
|
|
|
11
|
+
MX = Monitor.new
|
|
12
|
+
|
|
11
13
|
def initialize(pool, ttl: DEFAULT_KEY_TTL.to_i, logger: nil)
|
|
12
14
|
@pool = pool
|
|
13
15
|
@ttl = ttl
|
|
14
16
|
@logger = logger || Logger.new(STDOUT)
|
|
15
17
|
@logger.level = Logger::DEBUG
|
|
16
18
|
# load_redis_scripts
|
|
19
|
+
restore_lua_hashes
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
# Returns a list of limits matching the pattern
|
|
@@ -154,15 +157,45 @@ module Rapidity
|
|
|
154
157
|
#
|
|
155
158
|
# @return [void]
|
|
156
159
|
def load_redis_scripts
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
cls = self.class
|
|
161
|
+
MX.synchronize do
|
|
162
|
+
@pool.with do |conn|
|
|
163
|
+
list_lua_scripts.each do |script|
|
|
164
|
+
cls.instance_variable_set(lua_script_var(script),
|
|
165
|
+
conn.with {|r| r.script(:load, File.read(File.join(__dir__, 'lua_scripts', "#{script.to_s}.lua"))) }
|
|
166
|
+
)
|
|
167
|
+
end
|
|
162
168
|
end
|
|
163
169
|
end
|
|
170
|
+
restore_lua_hashes
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Restore instance script hashes from class cache
|
|
174
|
+
def restore_lua_hashes
|
|
175
|
+
cls = self.class
|
|
176
|
+
list_lua_scripts.each do |script|
|
|
177
|
+
instance_variable_set(lua_script_var(script), cls.instance_variable_get(lua_script_var(script)))
|
|
178
|
+
end
|
|
164
179
|
end
|
|
165
180
|
|
|
181
|
+
|
|
182
|
+
# это для тестов чтобы проверить перезугрузку сриптов
|
|
183
|
+
def reset_lua_scripts
|
|
184
|
+
cls = self.class
|
|
185
|
+
list_lua_scripts.each do |script|
|
|
186
|
+
instance_variable_set(lua_script_var(script), nil)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def list_lua_scripts
|
|
191
|
+
(BASE_SCRIPTS + self.class::LUA_SCRIPTS)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def lua_script_var(script)
|
|
195
|
+
"@lua_#{script}".to_sym
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
166
199
|
end
|
|
167
200
|
end
|
|
168
201
|
end
|
|
@@ -169,8 +169,8 @@ local function process_all_limits(limit_keys, requested, current_time)
|
|
|
169
169
|
limit:save()
|
|
170
170
|
|
|
171
171
|
-- Продлеваем жизнь ключу, чтобы он не удалился, если к нему активно обращаются.
|
|
172
|
-
--
|
|
173
|
-
redis.call("EXPIRE", limit.key, key_ttl
|
|
172
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
173
|
+
redis.call("EXPIRE", limit.key, key_ttl)
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
return { "result", "true", "keys", limit_keys }
|
|
@@ -134,8 +134,9 @@ local function process_all_queues(limit_keys, req_tokens, ttl)
|
|
|
134
134
|
limit:acquire(bottleneck_tokens)
|
|
135
135
|
limit:save()
|
|
136
136
|
|
|
137
|
-
-- Продлеваем жизнь ключу
|
|
138
|
-
|
|
137
|
+
-- Продлеваем жизнь ключу
|
|
138
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
139
|
+
redis.call("EXPIRE", limit.key, ttl)
|
|
139
140
|
end
|
|
140
141
|
|
|
141
142
|
-- Возвращаем успешный результат: сколько реально удалось захватить (tokens)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
-- 4. Поиск "узкого горлышка" (Bottleneck): Поскольку для успешной операции (в acquire.lua) нужны
|
|
18
18
|
-- токены из всех переданных лимитов одновременно, общим временем ожидания будет являться
|
|
19
19
|
-- максимальное время ожидания среди всех проверенных корзин (math.max(unpack(wait_times))).
|
|
20
|
-
-- 5. Поддержка TTL: В процессе проверки скрипт продлевает время жизни ключей (EXPIRE ...
|
|
20
|
+
-- 5. Поддержка TTL: В процессе проверки скрипт продлевает время жизни ключей (EXPIRE ...),
|
|
21
21
|
-- чтобы корзины не удалялись из Redis, пока за ними наблюдают ожидающие
|
|
22
22
|
-- процессы.
|
|
23
23
|
-- Обратите внимание: скрипт не изменяет количество токенов (не списывает их), а лишь "смотрит" на состояние.
|
|
@@ -132,7 +132,8 @@ local function process_all_limits(limit_keys, needed, time_now)
|
|
|
132
132
|
limit:update(time_now)
|
|
133
133
|
|
|
134
134
|
-- Продлеваем жизнь ключу, так как идет активная проверка лимита
|
|
135
|
-
|
|
135
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
136
|
+
redis.call("EXPIRE", limit.key, key_ttl)
|
|
136
137
|
|
|
137
138
|
-- Сохраняем время ожидания для текущего лимита
|
|
138
139
|
table.insert(wait_times, limit:available_in(needed))
|
|
@@ -36,9 +36,10 @@ local function check_queue()
|
|
|
36
36
|
|
|
37
37
|
local semaphore = tonumber(semaphore_str) or 0
|
|
38
38
|
|
|
39
|
-
-- Продлеваем жизнь ключу
|
|
39
|
+
-- Продлеваем жизнь ключу
|
|
40
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
40
41
|
-- так как идет активная проверка лимита.
|
|
41
|
-
redis.call("EXPIRE", limit_key, key_ttl
|
|
42
|
+
redis.call("EXPIRE", limit_key, key_ttl)
|
|
42
43
|
|
|
43
44
|
-- Возвращаем успешный результат и текущее доступное количество мест
|
|
44
45
|
return {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
-- Описание логики работы:
|
|
7
7
|
-- 1. Скрипт принимает ключ лимита и время его жизни (TTL).
|
|
8
8
|
-- 2. Если ключ существует, возвращает все его поля (HGETALL).
|
|
9
|
-
-- 3. При успешном чтении продлевает время жизни ключа (EXPIRE ...
|
|
9
|
+
-- 3. При успешном чтении продлевает время жизни ключа (EXPIRE ...),
|
|
10
10
|
-- чтобы предотвратить удаление активно используемых данных.
|
|
11
11
|
-------------------------------------------------------------------------------
|
|
12
12
|
|
|
@@ -28,8 +28,9 @@ local function info()
|
|
|
28
28
|
return {"result", "false", "error", "key_not_found"}
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
-- Продлеваем жизнь ключу
|
|
32
|
-
|
|
31
|
+
-- Продлеваем жизнь ключу
|
|
32
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
33
|
+
redis.call("EXPIRE", limit_key, key_ttl)
|
|
33
34
|
|
|
34
35
|
return {"result", "true", "info", {limit_key, data}}
|
|
35
36
|
end
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
-- Это критически важно: если мы просто обновляем настройки лимита "на лету",
|
|
15
15
|
-- мы не должны сбрасывать текущие ограничения и уже списанные пользователями токены.
|
|
16
16
|
-- 2. Расчет скорости (Rate): Скорость пополнения (rate) предрасчитывается прямо в Lua (max_tokens / interval) и кэшируется в Redis. Это избавляет от необходимости каждый раз высчитывать дроби при проверке (в скрипте acquire.lua).
|
|
17
|
-
-- 3. Управление временем жизни (TTL): Назначает ключу время жизни. Если ключ уже существовал, TTL продлевается
|
|
17
|
+
-- 3. Управление временем жизни (TTL): Назначает ключу время жизни. Если ключ уже существовал, TTL продлевается (EXPIRE ...).
|
|
18
18
|
-- 4. Возврат данных: Скрипт возвращает имя ключа и все его сохраненные поля (HGETALL). В Ruby эта структура затем используется для сборки (гидратации) объекта Limit.
|
|
19
19
|
-------------------------------------------------------------------------------
|
|
20
20
|
|
|
@@ -55,8 +55,9 @@ local function init()
|
|
|
55
55
|
"rate", rate
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
-- Продлеваем жизнь ключу
|
|
59
|
-
|
|
58
|
+
-- Продлеваем жизнь ключу
|
|
59
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
60
|
+
redis.call("EXPIRE", limit_key, key_ttl)
|
|
60
61
|
else
|
|
61
62
|
-- Создание нового лимита.
|
|
62
63
|
-- Корзина инициализируется как полностью заполненная (tokens = max_tokens).
|
|
@@ -120,8 +120,9 @@ local function process_all_queues(limit_keys, released_tokens, ttl)
|
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
-- Продлеваем жизнь ключу
|
|
124
|
-
|
|
123
|
+
-- Продлеваем жизнь ключу
|
|
124
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
125
|
+
redis.call("EXPIRE", limit.key, ttl)
|
|
125
126
|
end
|
|
126
127
|
|
|
127
128
|
-- Если ни у одного лимита очередь не включена, вернем 0
|
|
@@ -51,8 +51,9 @@ local function reset()
|
|
|
51
51
|
"last_used", current_time
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
-
-- Продлеваем жизнь ключу
|
|
55
|
-
|
|
54
|
+
-- Продлеваем жизнь ключу
|
|
55
|
+
-- раньше был GT, но он только с версии 7 (GT - только если новый TTL больше текущего остатка)
|
|
56
|
+
redis.call("EXPIRE", limit_key, key_ttl)
|
|
56
57
|
|
|
57
58
|
-- Возвращаем успешный результат и обновленные данные
|
|
58
59
|
return {"result", "true", "info", {limit_key, redis.call("HGETALL", limit_key)}}
|
data/lib/rapidity/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rapidity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.8.373806
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yurusov Vlad
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-
|
|
12
|
+
date: 2026-05-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|