jaredwray / flat-cache

A stupidly simple key/value storage using files to persist the data
MIT License
165 stars 30 forks source link

Cache Expiration #38

Closed zachjharris closed 1 year ago

zachjharris commented 5 years ago

Is there a way to set an expiration time on a cache item? For instance say I want to cache results from a weather API - it's not necessary to make the API request every 5 minutes if the page that needs the data is accessed that often. Something like this would be ideal:

cache.setKey('key', 'value'); cache.save(60); // cache lasts for 60 min

And to erase expired items: cache.eraseExpired();

If nothing like this exists I will create a PR. Also this is my first time posting to GH, hopefully the formatting isn't too jacked up.

royriojas commented 5 years ago

hi @zachjharris

Formatting is not an issue. And thank you for your feedback.

The main purpose of this module was to have a storage that is written only once to disk at the end of a cli execution process (to avoid intermediate read/write operations)

I'm open to consider changes to the API, but I would encourage you first to check if other modules might suit your needs closer than this one.

In any case it might be an interesting approach to set a time to expire the values, I would say that reading from the cache should be enough to check if a value is valid or not. And the next save might perform the cleaning of the expired values, by just removing it from the object that is serialized.

p1ho commented 5 years ago

@zachjharris I know this is from almost 2 months ago; but in case you're still looking for a solution, I had to implement something similar to what you're asking. I basically wrote a class on top of it that handles expiration for each key/value pair (Link to Gist).

const flatCache = require('flat-cache')
class Cache {
  constructor (name, path, cacheTime = 0) {
    this.name = name
    this.path = path
    this.cache = flatCache.load(name, path)
    this.expire = cacheTime === 0 ? false : cacheTime * 1000 * 60
  }
  getKey (key) {
    var now = new Date().getTime()
    var value = this.cache.getKey(key)
    if (value === undefined || (value.expire !== false && value.expire < now)) {
      return undefined
    } else {
      return value.data
    }
  }
  setKey (key, value) {
    var now = new Date().getTime()
    this.cache.setKey(key, {
      expire: this.expire === false ? false : now + this.expire,
      data: value
    })
  }
  removeKey (key) {
    this.cache.removeKey(key)
  }
  save () {
    this.cache.save(true)
  }
  remove () {
    flatCache.clearCacheById(this.name, this.path)
  }
}

You can then instantiate your cache this way

var cache = new Cache('test', 'path-to-cache', 60)

Hope this is helpful!