Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Advanced custom cache keys #52

Open
jeromedalbert opened this issue Mar 26, 2019 · 4 comments
Open

Advanced custom cache keys #52

jeromedalbert opened this issue Mar 26, 2019 · 4 comments
Labels
enhancement New feature or request Refactor

Comments

@jeromedalbert
Copy link
Contributor

jeromedalbert commented Mar 26, 2019

I am not sure that this is a good idea. I will need to think more about that tomorrow or if I even actually need to to this. But here is my idea dump right now for future reference.

My use case is that my custom cache key value is potentially complicated and would need:

  • a lambda/proc on multiple lines (not super elegant, but already possible?)

    field :some_field, String, cache: { key: ->(obj) {
      "#{obj.id}123blah"
    } } do
      ...
    end
  • its own line, e.g.

    field :calculated_field, Int do
      cache <complicated code block goes here>
    end
  • or even its own method within the enclosing Type class.

    field :calculated_field, Int, cache: { key: :custom_cache_key }

    where :custom_cache_key is first looked up in the instance of the enclosing type class that is defining this field (with respond_to?) and only then calls the parent object if it's not defined.

  • or just use Rails.cache.fetch blocks manually inside the resolver

@jeromedalbert jeromedalbert changed the title Complicated cache keys More custom cache keys Mar 26, 2019
@jeromedalbert jeromedalbert changed the title More custom cache keys Advanced custom cache keys Mar 26, 2019
@thebadmonkeydev
Copy link
Collaborator

@jeromedalbert thanks for pointing this out. There seems to be a use case that we don't really cover with overridden keys. Looking through the code, I'm starting to think the whole key construct could be refactored to be a bit more readable and maintainable. I'm going to open a PR later today to start off that process.

I'm thinking maybe break key up somehow along the lines of type as evaluated here Identify the type of key based on metadata[:key] and instantiate the approriate class so that we can move features like context passing (#49) or more advanced usage of the object method approach (this issue) into their own classes. Suggestions are certainly welcome 😃

@thebadmonkeydev thebadmonkeydev added enhancement New feature or request Refactor labels Mar 26, 2019
@thebadmonkeydev thebadmonkeydev self-assigned this Mar 26, 2019
@thebadmonkeydev
Copy link
Collaborator

Starting up a refactor over on #50 that will fix that specific issue along with making it possible to provide a custom key generation class of some kind which will give you all the tools necessary for controlling the cache keys for specific fields.

@jeromedalbert
Copy link
Contributor Author

jeromedalbert commented Apr 2, 2019

I hope this issue is not too much of a hassle or waste of time, because I don't find myself often needing this. If it is a hassle, feel free to close!

Maybe needing complicated cache keys is a code smell telling me to instead cache upstream (Rails fragment/page caching), cache downstream (plain Rails.cache.fetch calls in the resolver), or avoid caching altogether.

@thebadmonkeydev
Copy link
Collaborator

Though it's not often used, I think the current implementation is a little stilted in it's flexibility. I think a feature like cache_if along with the ability to define a custom object to pass as the key generator is useful. The latter is just a matter of changing our checks from is_a? Proc to checking that it responds to call. This would allow you to create arbitrarily complex cache keys simply by providing an object that responds to call (this technique is used in graphql-ruby with several tracers, instead of using a long, difficult to read Proc, they instantiate a service object that responds to call). I'm going to leave this open for now and close it as part of a refactor I'm working on.

@thebadmonkeydev thebadmonkeydev removed their assignment Aug 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request Refactor
Projects
None yet
Development

No branches or pull requests

2 participants