Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: provide means of not caching certain values #5

Open
vrurg opened this issue Jul 30, 2019 · 5 comments
Open

Feature request: provide means of not caching certain values #5

vrurg opened this issue Jul 30, 2019 · 5 comments

Comments

@vrurg
Copy link
Contributor

vrurg commented Jul 30, 2019

I'm trying to cache DB records. In my case if a record is not found now doesn't mean it won't be created any time soon. Moreover, it is likely to be created. For this reason it would make sense to skip Nil returned by the producer.

There're two possible ways of handling this situation. More complicated yet more flexible one would be to handle a special control exception. Something like:

class CX::Cache::Async::Bypass is X::Control { 
    has Mu $.return-value;
}
sub bypass( Mu $return-value ) is export {
    CX::Cache::Async::Bypass.new(:$return-value).throw
}

Mu here is to allow returning type objects.

The use by a producer would be:

sub producer( $key ) {
    my $ret;
    ...
    if $non-cachable {
        bypass $ret
    }
    $ret
}
@vrurg vrurg changed the title Feature request: provides means of not caching certain values Feature request: provide means of not caching certain values Jul 30, 2019
@robertlemmen
Copy link
Owner

totally, no idea how I could have lived without this ability so far!

an obvious and simple way to do it would be to not cache undefined return values, and perhaps have a setup parameter that says whether these are cached or not.

You solution of using an exception would be an option as well, but it is a bit more involved and implements a "regular" code path via an exception, not sure how expensive and tasteless that is.

yet another way would be to return a "special" value from the producer to signal "no-value-do-not-cache"

and finally I wonder how this intersects with another, planned, feature where one can get a value through the cache (so using the cached value if one is present), but not updating the cache in any case. This is great if you do requests that do not follow the normal access patterns and would therefore destroy the LRU properties. It is similar with the "only" difference being whether it's the caller or the producer that decide whether the value is cached or not...

so lot's of food for thought, let me mull over it a while. And please let me know if you have any more input, greatly appreciated!

@vrurg
Copy link
Contributor Author

vrurg commented Jul 30, 2019

Not really much more input. You know this area better than I currently do. Just a note on using the control exception.

Because caching is supposed to speed up slow operations, even comparatively slow path of an exception would most likely be fast enough for the overall performance. Besides, it can be explicitly stated in the docs that use of bypass is slower than... whatever other solution will be there.

As to myself, I have implemented the control exception by relying on the fact that await unwrapping a Promise explodes with the contained exception. And if I catch my own CX::BOT::NoRecord one I just remove corresponding key from the cache. Not sure if this is any way faster than not storing it in the first place.

I saw your get-through idea. It's a fast thinking, but bypassing and get-through are orthogonal from the point of view that anyone using both of them just have to understand how things work. Any other approach would likely result in obscure behaviors.

@robertlemmen
Copy link
Owner

the idea that a control exception makes handling it somewhat easy is appealing indeed!

I have thought a bit more though, and realized that I have another case where I need to return a value plus some extra info from the producer: where the expiry time should be set by the producer. So I want to use a common format for both. I'll try using a wrapper value instead of an exception at first and see how that goes...

@robertlemmen
Copy link
Owner

fwiw, I have also added the most common case, not caching undefined values, as a general c'tor enabled feature in the latest master. will add the more fine-grained and powerful version soon as well

@vrurg
Copy link
Contributor Author

vrurg commented Aug 13, 2019

Just as a note: I had to suspend the project where I used Cache::Async. So, for a while I couldn't be a great tester, unfortunately.

But I'll be following for as long as I can because it had great experience with the module. Now I will always know where to look for if I need caching again! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants