apollographql / apollographql/graphql-subscriptions
iterable.return() is not sufficient to clean up subscriptions
- Dominant language
- TypeScript
- Stars
- 1.6k
- Forks
- 129
- PR merge metrics
- No merged PRs in 30d
Description
Hey there 👋 This is perhaps a bug report and a bit of a question about how ya;'ll have implemented this.
We've been working on our own semi-internal implementation of subscriptions for graphql and come across an issue handling the pub-sub case, one that seems like ya'll suffer from as well (unless i'm missing something)
The crux of the issue is that `iterable.return()` doesn't get called when an iterable hasn't started. which means once you've used language level constructs to map or filter an iterable it'll never clean up unless it's already had a value pulled
Following will run in Chrome if you paste it into a console:
```js
let f = (()=> {
let i = 0
return {
next() {
return Promise.resolve({ value: i++, done: i >= 4 })
},
return() {
console.log('return!')
return Promise.resolve({ value: undefined, done: true });
},
throw(error) {
return Promise.reject(error);
},
[Symbol.asyncIterator]() {
return this
}
}
})()
async function* addOne() {
for await (const val of f) yield val + 1;
}
await addOne().return();
```
The practical problem is that if you disconnect or unsubscribe from a subscription before it pushes a value, the underlying pup-sub will never clean itself up.
Contributor guide
Research direction
Start with the async-iterator reproducer in the issue, especially the behavior of addOne().return() before the iterator has yielded. Trace how graphql-subscriptions creates and disposes subscription iterables, then verify whether an unsubscribe before the first value reaches the underlying pub-sub cleanup. Done means the underlying subscription is cleaned up in that case and the behavior is covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- api, backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100