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

Let getFreshValue know whether the update is happening in the background or not #24

Closed
kentcdodds opened this issue Jan 18, 2023 · 7 comments

Comments

@kentcdodds
Copy link
Member

Here's what I've got:

function abortTimeoutSignal(timeMs: number) {
  const abortController = new AbortController()
  void new Promise(resolve => setTimeout(resolve, timeMs)).then(() => {
    abortController.abort()
  })
  return abortController.signal
}

async function gravatarExistsForEmail({
  email,
  request,
  timings,
  forceFresh,
}: {
  email: string
  request: Request
  timings?: Timings
  forceFresh?: boolean
}) {
  return cachified({
    key: `gravatar-exists-for:${email}`,
    cache: lruCache,
    request,
    timings,
    forceFresh,
    ttl: 1000 * 20,
    staleWhileRevalidate: 1000 * 60 * 60 * 24 * 365,
    checkValue: prevValue => typeof prevValue === 'boolean',
    getFreshValue: async () => {
      const gravatarUrl = getAvatar(email, {fallback: '404'})
      try {
        const avatarResponse = await fetch(gravatarUrl, {
          method: 'HEAD',
          signal: abortTimeoutSignal(1000 * 2),
        })
        return avatarResponse.status === 200
      } catch (error: unknown) {
        console.error(`Error getting gravatar for ${email}:`, error)
        return false
      }
    },
  })
}

I have the abortTimeoutSignal thing in place so gravatar won't cause me issues if my page is waiting on it. I think if my page is waiting on it I'd prefer that the timeout time be more like 500ms, but if the update is happening in the background (SWR) then I'm fine with it taking even 10 seconds. Thoughts? Maybe an argument passed to getFreshValue?

@Xiphe
Copy link
Collaborator

Xiphe commented Jan 19, 2023

Hi Kent 👋 Sounds useful to me 👍

To be clear: When you say "In the background", you mean a case where the cachified call returned a stale cache value and getFreshValue is called in the background to eventually provide a fresh value for the next call right?

@kentcdodds
Copy link
Member Author

Exactly 👍

Xiphe added a commit that referenced this issue Jan 19, 2023
so that implementation can behave differently for background refresh scenarios

fix: #24
@Xiphe
Copy link
Collaborator

Xiphe commented Jan 19, 2023

Could you give cachified@3.1.0-context-info.1 a try?

The info is passed on the new GetFreshValueConext

cachified({
  /* ... */   
  ttl: 5,
  staleWhileRevalidate: 20,
  getFreshValue({ background }) {
    console.log(background);
    return 'value'
  }
});

@kentcdodds
Copy link
Member Author

Sweet! I'll give this a try soon and report back. Thanks!

@kentcdodds
Copy link
Member Author

Works great 👍 Thank you.

@Xiphe Xiphe closed this as completed in 9c53976 Jan 25, 2023
@Xiphe
Copy link
Collaborator

Xiphe commented Jan 25, 2023

Glad to hear that! It's released under v3.1.0

@kentcdodds
Copy link
Member Author

Super, thanks a lot :)

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