-
-
Notifications
You must be signed in to change notification settings - Fork 43
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
Using async cache dedupe for http request caching #99
Comments
If not let's make it so. Wdyt @simone-sanfratello? |
There are a few decision we should take, let me explain how to identify the requestThe function should identify the request by:
My idea is to provide a default function with options to do so, along with the possibility to use a custom function, where the output must be an object (or a string) that identify the request (note for further optimization, since request has a know structure, should use a custom serializer) example - pseudocode export function defineCache ({ cache, options }) {
cache.define('request', {
serialize: options.serialize ?? async (request) => {
// TODO implement an ergonomic and performant way to describe so, to be passed in options
for(const option in options) {
if (match(request, option)) {
return serializeRequest(request, option)
}
// don't use cache if no matched
}
},
(request) => undici.request(request)
})
}
// example of options, there will be probably more ways or different ones, to be defined during implementation
const options = [
{
url: /$https:\/\/server\/user\/[0-9a-f]+/,
method: 'GET',
headers: ['content-type','authorization'],
query: [] // ignore querystring
},
{
url: 'https://server/users',
method: 'GET',
headers: ['content-type'],
query: '*' // consider the whole querystring
},
] using a custom logic options.serialize = (request) => {
if (request.url.match('http://server/users/:id') && request.url == 'GET') {
return serializeRequest({
method,
url,
querystring,
headers: pick(request.headers, ['authorization']) })
}
if (request.url == 'http://server/items' && request.url == 'GET') {
return serializeRequest({
method,
url,
querystring,
headers: pick(request.headers, ['content-type']) })
}
// else don't use cache
} how to get and set headersImo the function should provide the capabilities for the user to:
cache.define('request', {
ttl: 30,
// ...
},
(request) => {
// HERE request.headers['cache-control'] will be set to 'max-age=30'
return undici.request(request)
}
}) This is not currently supported, should be implemented
This function should support the http caching headers, for example: if cache.define('request', {
ttl: 30,
// ...
onResponse: (response) => {
// if response.headers['cache-control'] is 'max-age=30'
if (response.headers['cache-control']) {
const cacheControl= parseCacheControl(response.headers['cache-control'])
const ttl = cacheControl['max-age']
return { ttl, response }
// same for stale as in ronag example
}
}
},
(request) => {
// request here will have here
// request.headers['cache-control'] = 'max-age=30'
return undici.request(request)
}
})
Same as above: if cache is been used, and server request is not performed, response headers may add caching headers like how to release it / how to use itCould be releases as a plugin of this library like 'undici-cache' or so, so the usage can be import cache from 'undici-cache'
import undici from 'undici'
const undiciCached = cache(undici, options)
// undiciCached has the undici methods
undiciCached.request(...) While it's not a small piece of work, that would be a really cool feature, I'd be very happy to write it, let me write a poc |
I think you can be more generic that |
Sure, it's just a draft to share ideas |
Agreed! |
I would like to use async cache dedupe for http request caching. However, I'm missing a way to set the stale value on a per entry basis after the request is completed, i.e.
Any ideas whether this would be possible to add?
The text was updated successfully, but these errors were encountered: