jaemk / cached

Rust cache structures and easy function memoization
MIT License
1.57k stars 95 forks source link

add fallback feature #177

Closed Raz-Hemo closed 10 months ago

Raz-Hemo commented 10 months ago

Allows for returning the last valid cache value in the case of a fallible function. Useful for example in network disconnections, where you might want to stay operating until everything returns to normal.

jaemk commented 10 months ago

Thanks @Raz-Hemo ! Can you move the code block that retrieves the old value to only run when there’s an error? Also need to add a line to the doc string here explaining it https://github.com/jaemk/cached/blob/1eeba95a8b6f4297b3e4b3251c8795bcc5251ffd/cached_proc_macro/src/lib.rs#L38

Raz-Hemo commented 10 months ago

I actually tried to get the old value only on error in the beginning, but it turned out the cache cleared when calling cache_get in the first block, so by the time we know we need to retrieve it, it's already gone. I'm not sure if there is an alternative to the small performance hit of cloning the value every time the function is called, what do you think?

jaemk commented 10 months ago

Oh that's a good point. Looking at this again I also noticed you're calling get_store cache.get_store().get(&key) which isn't a trait method so this wouldn't work for all stores as is.

I think we need to introduce a new trait method cache_get_expired(self, key: &K) -> (Option<K>, bool) where an optional clone of K is always returned and a bool specifying whether that K was just evicted. Would you mind adding this and an impl to every store (excluding the IO ones, this wouldn't be possible with redis for example)?

Then the macro can call this method when result fallback is true instead of the regular cache get. There's the clone every time, but there's no way around that in this case since the eviction case requires transferring ownership

Raz-Hemo commented 10 months ago

I've tried to do this but just now realized that i had to add a Clone bound to the V in all cache types. I do think this will break people using the cache structs without the proc macro, with types that do not implement Clone.

So instead i made a new trait just for this function, let me know if the code makes sense.

jaemk commented 10 months ago

Thanks a bunch @Raz-Hemo ! Released in 0.48.0