relay: Bug: Cache in SSR

I found requestCache caused a bug. In server side, componentDidUpdate never be called. As a result, requestCache never be cleaned.

I used react-relay-network-modern-ssr in my project and this was ok when I loaded the website for the first time. This queried data correctly. However, after I reload the website, this did not request again to get the newest data.

Because nodejs never import each module again, requestCache will never be cleaned in server.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 10
  • Comments: 26 (13 by maintainers)

Most upvoted comments

We’re actively working on suspense-compatible APIs, which will include addressing issues such as these. Stay tuned!

Hi all! I can confirm the issue too with a different implementation of Relay SSR than the used in @HsuTing example.

The real problem is that the requestCache[key] is only cleared in componentDidMount, which never happens on SSR: https://github.com/facebook/relay/blob/master/packages/react-relay/modern/ReactRelayQueryRenderer.js#L189-L194

Because of that, the “request” is always in flight: https://github.com/facebook/relay/blob/master/packages/react-relay/modern/ReactRelayQueryRenderer.js#L365

Would be nice to have a way to force that fetch someway, maybe with an extra prop in the QueryRender component that I can set when process.browser is false.

Its experimental fix, QueryRenderer cache is still object and can grow until sigabort

see https://github.com/facebook/relay/blob/master/packages/react-relay/ReactRelayQueryRenderer.js#L58

this is fixed on relay-hooks https://github.com/relay-tools/relay-hooks/issues/7

you can try that for now

Could this request cache also potentially leak data to unauthorized users? If the same query is issued with different environments with different authorization levels, the user with less authorization could potentially get the cached response from the user with higher authorization?

Not fixed, still huge memory leak

We’ve been struggling with this as well.

The only way we’ve been able to ensure that the query is actually fetched under SSR is to include a nonce variable (variables are used as part of the cache key) - but this creates a memory leak, as the cache grows with every request and is never cleared.

@josephsavona any progress that could help us out? We’re planning to fork ReactRelayQueryRenderer to fix our immediate issue, but would be good to have a proper fix on the Relay side!

I’m not awaiting, just some code is run client-side only. It wasn’t an issue for 1+ year for us until our traffic suddenly become 30 req/s from like 0.1 req/sec. (We use it mostly to update client dependent information to have SSR aware of user details) And we get that Query Renderer leaks 😉 So now we wrapped it. Probably it should use weakmap too, or warn once at dev mode about server side usage. (In our case we just check on typeof window)