object-cache icon indicating copy to clipboard operation
object-cache copied to clipboard

Add the option to return _stale_ values whilst refreshing in background

Open koenbollen opened this issue 9 years ago • 0 comments

Currently this gem allows values to be cached until the expire, when this happens a new value is generated, cached and returned. This means that every ttl one user/client/connection needs to wait for the cache to refresh.

It would be great if you could specify the time after which a value is stale (time to stale?). Where stale means the value can still be used but a new version should be generated in the background.

Ex:

def get_highscore
  Cache.new(tts: 5.minutes, ttl: 10.minutes) {
    get_resource('https://example.org/api/highscore.json')
  }
end

# snip…snip…snip

puts get_highscore # first time, fetches data

sleep 1.minute
puts get_highscore # use cache

sleep 5.minutes
puts get_highscore # cache is stale, method returns immediately background job fetches new data
puts get_highscore # background job might still be busy, stale cache still used, no second job started

sleep 5.seconds
puts get_highscore # new data is used, timers reset

sleep 15.minutes
puts get_highscore # value completely expired, method blocks to fetch new data.

This way values are kept up-to-date and no user/client/connection has is blocked every once and a while.

Two more ideas:

  • Pluggable backend, defaulting to Thread.new. If this gem is used in an eventmachine environment eventmachine should be used.
  • Automatic stale. If you measure the average time a refresh takes, you can predict when a new version should be fetch. ex: tts = ttl - (measured_time*2) (this should be disabled by default).

Cheers, —Koen

koenbollen avatar Dec 13 '16 10:12 koenbollen