У нас есть сервер, который становится капризным, если слишком много пользователей входят в систему одновременно (то есть с интервалом менее 7 секунд). После того, как пользователи вошли в систему, проблем нет (один или два входа одновременно тоже не проблема, но когда 10-20 попыток, весь сервер уходит в смертельную спираль вздох) .
Я пытаюсь написать страницу, которая будет удерживать пользователей (отображать анимированный обратный отсчет и т. д.) и позволять им проходить через 7 секунд. Алгоритм прост
- получить отметку времени (t), когда произошел последний вход в систему
- если
t+7
в прошлом, запустите логин и сохранитеnow()
в качестве новой метки времени - если
t+7
будет в будущем, сохраните его как новую отметку времени, подождите доt+7
, затем начните вход в систему.
Прямая реализация python/redis будет:
import time, redis
SLOT_LENGTH = 7 # seconds
now = time.time()
r = redis.StrictRedis()
# lines below contain race condition..
last_start = float(r.get('FLOWCONTROL') or '0.0') # 0.0 == time-before-time
my_start = last_start + SLOT_LENGTH
r.set('FLOWCONTROL', max(my_start, now))
wait_period = max(0, my_start - now)
time.sleep(wait_period)
# .. login
Состояние гонки здесь очевидно, на линии my_start =
одновременно может находиться много процессов. Как я могу решить это с помощью Redis?
Я пробовал функцию redis-py pipeline
, но, конечно, она не получает фактического значения до вызова r.get()
...