cachified: TTL must be slightly longer than the time it takes for the promise to resolve.

In my use case I was trying to set ttl: 0 and staleWhileRevalidate: Infinity so that every request after the initial request would always trigger a refetch in the background, however in my tests, if the ttl value is less than the time the promise takes, it will ALWAYS refetch.

This is my example that always refetches.

  return await cachified({
    key: "test",
    cache: cache,
    getFreshValue: () =>
      new Promise((resolve) => {
        setTimeout(() => {
          console.log("resolving");
          resolve(new Date().toLocaleString());
        }, 5000);
      }),
    ttl: 3000,
    staleWhileRevalidate: Infinity,
  });

And if I change the promise timeout to 2000, it will always return the cached value and refetch in the background (after the ttl).

return await cachified({
    key: "test",
    cache: cache,
    getFreshValue: () =>
      new Promise((resolve) => {
        setTimeout(() => {
          console.log("resolving");
          resolve(new Date().toLocaleString());
        }, 2000);
      }),
    ttl: 3000,
    staleWhileRevalidate: Infinity,
  });

And because of this I can’t set the ttl to 0 to get my desired outcome.

Let me know if you need any additional info, thanks for this library it’s exactly what I’ve been looking for!

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (1 by maintainers)

Most upvoted comments

@Xiphe you are absolutely right - the cache is not hit if we set ttl to -1. This pattern works really well for me, thank you 🙏

If anyone wants to contribute documentation on this point that is welcome! 😃

Thanks for the additional conversation here, that’s helpful for me!

For my uses cases, I’m wrapping the cachified function to add some defaults. Based on the above convo I updated it to this, which seems to do what I was initially talking about.

Is there negative impacts of this that I’m not aware of?

return cachified({
  ttl: ms("1m"),
  ...options,
  cache: lru,
  key: keyPrefix + options.key,
  async getFreshValue(context) {
    const freshValue = await options.getFreshValue(context);

    /**
     * Set the created time for the cache entry to now,
     * this allows the ttl to start from the time the
     * the value was returned from the `getFreshValue` function.
     */
    context.metadata.createdTime = Date.now();

    return freshValue;
  },
});