Expiration by time
tdakkota opened this issue · 2 comments
some KV stores like Redis and Memcached can automaticly remove expired keys, but gokv can't
I saw the first item of Design decisions, but i think that gokv can provide multiple interfaces, like gokv.Cache
Hi @tdakkota, thanks for the feature request!
You're right that another interface could be added to the root gokv
package and that wouldn't have any negative consequences to packages using gokv.Store
so far (like added dependencies or so).
Regarding the implementations it's a little bit more difficult: Redis and Memcached have native support for key-value pair expiration, but other products that have implementations for gokv.Store
already don't have this.
There are some ways to implement that on your own:
- Each
xyz.Set("key", "val", expiration)
call could lead to a goroutine with a timer that callsxyz.Delete("key")
after the expiration, but that wouldn't work as soon as the program crashes or something - When
xyz.Set
is called, it could add its own metadata in addition to the value, with the metadata including the expiration date. Axyz.Get
call would lead togokv
checking the expiration in the metadata, deleting the value if the expiration is reached, or otherwise return the actual value. This would lead to the package behaving like a cache, but the cache might actually grow very big due to stale entries that are just not deleted because noxyz.Get
was called on them yet.- This could be mitigated by a goroutine that runs in the background every now and then to go through all key-value pairs, check their expiration and remove the expired ones. This requires a way to retrieve all key-value pairs though and I'm not sure if all products that have implementations for
gokv.Store
support this. (It's the same issue for #9).
- This could be mitigated by a goroutine that runs in the background every now and then to go through all key-value pairs, check their expiration and remove the expired ones. This requires a way to retrieve all key-value pairs though and I'm not sure if all products that have implementations for
- Maybe other ways?
An alternative would be to only support the products that contain an expiration mechanism on their own, like Redis and Memcached. That might lead to confusion by people who use gokv.Store
and think something like "when I use this gokv interface I know my package users who use product xyz can use it" and presume the same goes for the cache interface. Although maybe this could be mitigated with good documentation. For example the README could contain a table (instead of the current Implementations list) with the interfaces as columns and the products as rows, like:
Package | gokv.Store |
gokv.Cache |
---|---|---|
redis |
✔️ | ✔️ |
file |
✔️ | ❌ |
Which would you prefer? (Only support the products with expiration support vs. implementing cache entry deletion on our own for products without expiration support)