我有一個簡單的Ruby方法,旨在遏制一些執行。Rails緩存計數器
MAX_REQUESTS = 60
# per
TIME_WINDOW = 1.minute
def throttle
cache_key = "#{request.ip}_count"
count = Rails.cache.fetch(cache_key, expires_in: TIME_WINDOW.to_i) { 0 }
if count.to_i >= MAX_REQUESTS
render json: { message: 'Too many requests.' }, status: 429
return
end
Rails.cache.increment(cache_key)
true
end
經過一番測試,我發現cache_key
永不會失效。
我研究了binding.pry
,發現問題:
[35] pry(#<Refinery::ApiReferences::Admin::ApiHostsController>)> Rails.cache.write(cache_key, count += 1, expires_in: 60, raw: true)
=> true
[36] pry(#<Refinery::ApiReferences::Admin::ApiHostsController>)> Rails.cache.send(:read_entry, cache_key, {})
=> #<ActiveSupport::Cache::Entry:0x007fff1e34c978 @created_at=1495736935.0091069, @expires_in=60.0, @value=11>
[37] pry(#<Refinery::ApiReferences::Admin::ApiHostsController>)> Rails.cache.increment(cache_key)
=> 12
[38] pry(#<Refinery::ApiReferences::Admin::ApiHostsController>)> Rails.cache.send(:read_entry, cache_key, {})
=> #<ActiveSupport::Cache::Entry:0x007fff1ee105a8 @created_at=1495736965.540865, @expires_in=nil, @value=12>
所以,increment
被殲滅expires_in
值和改變created_at
,經常寫會做同樣的事情。
我該如何預防?我只想爲給定的緩存鍵更新的值。
UPDATE
每建議我嘗試:
MAX_REQUESTS = 60
# per
TIME_WINDOW = 1.minute
def throttle
cache_key = "#{request.ip}_count"
count = Rails.cache.fetch(cache_key, expires_in: TIME_WINDOW.to_i, raw: true) { 0 }
if count.to_i >= MAX_REQUESTS
render json: { message: 'Too many requests.' }, status: 429
return
end
Rails.cache.increment(cache_key)
true
end
無影響。緩存不會過期。
感謝您的迴應!嘗試它(見上文)沒有奏效。我錯過了什麼? – lostphilosopher
它適用於我,看到更新的答案。你有沒有嘗試上面的簡單測試?你在使用什麼緩存存儲?它可能無法在所有緩存存儲中以相同的方式工作。我使用Dalli gem在memcached上測試了所有這些。 – BoraMa
呵呵,試過你提供的代碼,在我的項目的rails runner下運行它,同樣的問題,在60後永遠存在「太多的請求」。我確定我的'cache_store'是':memory_store'。接下來,我將嘗試在我的項目中設置'dalli'和':mem_cache_store'。 (Rails 4.2.7.1供參考。) – lostphilosopher