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

Notify successful fresh cache retrieval #46

Open
kitmonisit opened this issue Feb 25, 2021 · 2 comments
Open

Notify successful fresh cache retrieval #46

kitmonisit opened this issue Feb 25, 2021 · 2 comments

Comments

@kitmonisit
Copy link

Hi, I'd like to propose an enhancement similar to verbose_cache.

I will call the new keyword argument notify_fresh. The wrapped function will return a tuple where the second value indicates if the value was fresh from cache.

This will enable logic outside the scope of the cached function to make decisions based on whether the data came from the cache.

For example, let's pretend we have a snobby server that hates being asked too many questions in rapid succession. If we get our answer fresh from the cache, then we can ask the next question right away:

@cachier()
def small_talk_to_snobby_server(query):
    response = "I'm fine, thank you!"
    return response

if __name__ == "__main__":
    response, is_fresh = small_talk_to_snobby_server(query="How are you?", notify_fresh=True)
    if not is_fresh:
        sleep(60)
    response = small_talk_to_snobby_server(query="What are you up to these days?")

Some self-critique

I find it rather clunky and API-breaking to make functions return a different data type than expected. I do not know any other way around this.

@shaypal5
Copy link
Collaborator

shaypal5 commented Mar 9, 2021

Hey Kit! :)

Thank you for making this suggestion, and offering a PR and being active!
The use case sounds solid, but it's definitely not the right implementation.

I would suggest providing the notify_fresh keyword with a "listener" object, in which the information you want to get will be stored by cachier. Than, you can check it's value after the value returns to get more information about the cache process involved in fetching said value.

For example:

@cachier()
def small_talk_to_snobby_server(query):
    response = "I'm fine, thank you!"
    return response

if __name__ == "__main__":
    freshness = Freshness()
    response = small_talk_to_snobby_server(query="How are you?", notify_fresh=freshness)
    if not freshness.value:
        sleep(60)
    response = small_talk_to_snobby_server(query="What are you up to these days?")

We will also want a generalized design, to ride the same API for more information, so this is better, I think:

if __name__ == "__main__":
    cinfo = CachierInfo()
    response = small_talk_to_snobby_server(query="How are you?", info=cinfo)
    if not cinfo.fresh:
        sleep(60)
    response = small_talk_to_snobby_server(query="What are you up to these days?")

What say you?

@kitmonisit
Copy link
Author

Hi @shaypal5 thanks for the encouragement. And sorry for the delay, found the time to look at this just now.

That's a neat idea. I haven't dug deep into the code yet. Question, though: Certainly, when querying CachierInfo object for its fresh attribute, it needs to know which function I am referring to. So I imagine it stores the hash of the function call that's using it and associates it with a freshness boolean.

I'm not really familiar with function call hashes (other than that I've used function names as dict keys). A cursory glance of cachier's code base shows you make good use of hashes.

Am I on the right track?

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

Successfully merging a pull request may close this issue.

2 participants