suspend-react icon indicating copy to clipboard operation
suspend-react copied to clipboard

How to clean ressources ?

Open ScreamZ opened this issue 2 years ago • 9 comments

Any way to clean resources using this library. I would like to open a socket using suspense but when the Host change, i need to reload a new socket and would like to clean effect the previous.

ScreamZ avatar Mar 27 '23 10:03 ScreamZ

I too am wondering about this. I asked on Stackoverflow.

vezaynk avatar Oct 26 '23 20:10 vezaynk

you have clear, eg: https://github.com/pmndrs/drei/blob/4aa04c93e4e86711f0a5a6777482a92d52988253/src/core/FaceControls.tsx#L350

abernier avatar Oct 26 '23 21:10 abernier

@abernier so is the answer "use an effect"?

vezaynk avatar Oct 26 '23 21:10 vezaynk

that's how I did yes -- that way if a dep changes (same as your suspend, in my case videoTextureSrc), it will be cleaned up and cleared

abernier avatar Oct 26 '23 22:10 abernier

@abernier That's not ideal because it de-couples the effect from it's clean-up.

Suspend-react is aware of when the dependencies change, and so is best-positioned to run clean-up effects at the right time.

vezaynk avatar Oct 27 '23 00:10 vezaynk

I thought like you primarily, I even asked about that on Discord

From @drcmda's answer, I guess this decoupling is intentional:

suspense is a cache, unmount means nothing to a cached entry, it will continue to be available

which makes sense to me, it's a cache, nothing more

If you want more, like a side-effect when your cache-key changes, then you have useEffect

abernier avatar Oct 27 '23 06:10 abernier

I see.

Sounds like we should be wrapping suspend in our own hook.

Something like this.

const useSuspense(cb, deps) {
  const { value, cleanup } = suspend(cb)

  useEffect(() => {
    () => cleanup()
  }, deps)

 return value;
}

...but then we get the pitfall from a lack of reference-counting if two components use the same suspended keys.

useEffect(() => {
    () => {
      if (lastRef) evictFromCache();
      cleanup()
   }
  }, deps)

Makes me think suspend-react should be providing this.

vezaynk avatar Oct 27 '23 14:10 vezaynk

I found an implementation of a "useMemoCleanup" hook from here that performs cleanup.

i've been using it in my own project like so:

const texture = useMemoCleanup( () => 
		[
			suspend(async () => {
                            // your code here
                            return texture;
                        }, []), 

			// cleanup func
			() => {
				texture.dispose();
			}
		], [] );

and it seems to be working so far (even though i haven't heavily tested it)

hope this helps someone

nassosyian avatar Jul 17 '24 17:07 nassosyian

@nassosyian How does this work? Wouldn't the memorized value be lost when suspense throws to the boundary?

vezaynk avatar Jul 18 '24 20:07 vezaynk