akiomik / akiomik/nosvelte

useReq() has no teardown path once its query has settled

Ouverte
#61 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug
Langage dominant
TypeScript
Étoiles
29
Forks
3
Merge moyen
3 h 5 min
PR mergées (30 j)
11

Description

#60 closes a request's REQ when the query is cancelled mid-fetch, which is the
only teardown `useReq()` has. Once the query settles there is no longer anything
to cancel, so a subscription that outlives its consumer stays open.

This is reachable with a caller-supplied `req`. The oneshot req `useReq()` builds
for itself completes on EOSE and RxJS tears it down, but a forward req never
completes:

1. A component passes its own `RxReqBase` and the query resolves on the first event.
2. The component is destroyed. The query is already settled, so `removeObserver()`
has no in-flight retryer to cancel and the abort never fires.
3. The subscription stays live. Further `req.emit()` calls keep pushing events
through it and into `queryClient.setQueryData()` for a component that is gone.

Reactive re-invocation compounds it: components call the hooks from a reactive
statement (`$: result = useUniqueEventList(...)`), so each re-run builds a fresh
observable, and with the default `staleTime: 0` a remount refetches and subscribes
again — while the previous subscription is still running.

Fixing this needs a lifecycle hook `useReq()` does not have today. Rough options:

- Return an unsubscriber from `ReqResult` and have the components call it from
`onDestroy`. Explicit, but an API change for direct hook users.
- Tear down when the query's observer count drops to zero, via the query cache's
`observerRemoved` event. No API change, but Svelte's subscribe/unsubscribe
ordering across a reactive re-run can transiently hit zero observers, so it
needs care to avoid killing a subscription that is about to be re-adopted.

Worth noting while looking at this: `useReq()` calls `req.emit(filters)` before
anything subscribes to the query, so for a forward req that first emission is
dropped and no REQ is sent until the caller emits again. That may deserve its own
issue.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.