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

Wrong cache key #467

Open
gwen1230 opened this issue Mar 24, 2023 · 7 comments
Open

Wrong cache key #467

gwen1230 opened this issue Mar 24, 2023 · 7 comments

Comments

@gwen1230
Copy link

Hi !
I have a middleware that changes the request URI to sort query params, it works fine.
However, the caching middleware continues to use the premodified URI for caching.

Is there a solution to fix this problem?

@evert
Copy link
Collaborator

evert commented Apr 13, 2023

Hi!

Interesting issue! Indeed the a middleware would not be the right place to do this as it's too late at this point. I'm curious what the purpose is for sorting? If it's just to improve caching behavior, I wonder if it's sufficient to just subclass the Cache class and do a normalization step there.

But if you want to hook this into absolutely everywhere, there's a number of places where the URIs would need to be normalized. I would probably try to rewrite these as you are receiving the urls from the server.

@gwen1230
Copy link
Author

Hi !
Thank you for the answer !

It is indeed for a question of performance / use of the cache. Our backend returns links with href where one part of the query params is templated and not the other, in the following form: ?objectId=12&{from,to}.
However we also have a mechanism for invalidating the cache by our backend which returns in addition to one resource, the impacted resources with the href of the resource but this time there is no more template so our backend sorts the query params.

Example :
My backend returns a resource, with a link to http://localhost:3000/getobject?objectId=12&{from,to}, which therefore turns into http://localhost:3000/getobject?objectId=12&from=2023-01-01&to=2023-02-01 on follow, so it's this URL that is inserted into the cache. However during the following requests, our backend will return as impacted resource with href http://localhost:3000/getobject?from=2023-01-01&objectId=12&to=2023-02-01, ketting therefore does not invalidate the cache of the resource recovered...

I thought that making a middleware that sorts the params would be enough, but obviously not. I don't know if everything is clear.

@evert
Copy link
Collaborator

evert commented Apr 19, 2023

The issue is that there's a lot of potential places where URIs are passed along.

What mechanism do you currently used to invalidate the cache? This sounds like it's a job for Link: </foo>; rel="inv-by". The benefit of this is that you can you can have a 'main resource' that you use to invalidate caches, but also several other variant resources that always expire when the main one expires.

Regardless I do think it's kind of an interesting use-case and I wonder if Ketting should have a better mechanism for servers to specify their main url if there's variants

@gwen1230
Copy link
Author

To invalidate the cache, our backend returns in the links a list of impacted resources.
We have an interceptor on the frontend side which does a .go(res.href).refresh() on each of the impacted resources.
Linked resource logic is handled by our backend by adding elements to the impacted resources.

This works pretty well, except when the resource href has query params where the order has an impact 😁

@gwen1230
Copy link
Author

This is starting to be urgent for us, we have several bugs on our project because of this.
In your first message you suggested to create our own cache class, how to do that?

@evert
Copy link
Collaborator

evert commented Apr 24, 2023

Hey, honestly the best possible ways (in this order) are probably:

  1. Is there anything you can change so the same argument order for query parameters are emitted everywhere? It would be the simplest probably.
  2. If not, I would look at inv-by links so you can have multiple resources (or variants with the same url) expire together. Even though you still have duplicates in the cache this way, it shouldn't harm expiry.
  3. Find a way for ketting to normalize client-side. I mentioned a custom cache as an idea here but tbh I'm not 100% certain yet it will address all the corner cases. Caching is tricky stuff and urls are everywhere. A better idea might be to inspect self or canonical links and automatically tie those caches together too.

Here's the base class for caches: https://github.com/badgateway/ketting/blob/main/src/cache/forever.ts

If you have a budget also happy to consult a bit with this for a few hours.

P.S.: Also a dominion fan!

@gwen1230
Copy link
Author

Hello !
We just did a test by implementing our own cache and indeed it seems to work!
We have overwrite each method to use the sorted url rather than the input url and everything works correctly 🤷‍♂️

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