Reputation: 61
I'm making a service which retrieves a photograph from a remote host and does some processing before passing it on to the client. It caches the retrieved source photo locally to avoid retrieving it again later on.
However, if there are several requests in rapid succession, the source image will not yet have been saved locally, and unnecessary retrievals are performed.
What is a nice approach to defer the incoming requests until the source image is cached, provided it's already currently being retrieved?
I'm currently using Node.js streams all the way from the inbound request stream, passing it through my caching and transformation logic, passing it to the outbound stream.
Upvotes: 1
Views: 145
Reputation: 40394
You can cache the promise so all incoming requests to the same resource will only require one trip, avoiding flooding the database or some API.
const Cache = {};
function getPhoto(photoId) {
let cacheKey = `photo-${photoId}`;
let photoCache = Cache[cacheKey];
if (photoCache instanceof Promise)
return photoCache; //Return the promise from the cache
let promise = new Promise((resolve, reject) => {
if (photoCache) //Return the photo if exists in cache.
return resolve(photoCache);
return processPhoto(photoId).then(response => {
//Override the promise with the actual response
Cache[cacheKey] = response;
resolve(response);
}).catch(err => {
Cache[cacheKey] = null; //We don't want the rejected promise in cache!
reject();
});
});
if (!photoCache)
Cache[cacheKey] = promise; //Save the promise
return promise;
}
function processPhoto(photoId){
return new Promise((resolve, reject) => {
// Get the image from somewhere...
// Process it or whatever you need
//...
resolve('someResponse');
});
}
getPhoto
will return the same promise, when the promise is resolved, both requests will get the same response.Upvotes: 2