apollographql / apollographql/graphql-subscriptions
PubSub iterator promise never resolves if return() called too soon
- Dominant language
- TypeScript
- Stars
- 1.6k
- Forks
- 129
- PR merge metrics
- No merged PRs in 30d
Description
The following snippet will result in an iterator promise returned by `next()` that never resolves:
```js
const iterator = new PubSub().asyncIterator();
const promise = iterator.next();
iterator.return();
await promise; // will wait forever
```
The trick is that `return()` gets called synchronously while the first call to `next()` is still setting up its subscriptions.
This appears to be a regression since 1.0 since I have a test suite that was green and started failing on this issue when I upgraded to 1.1.
I have tried various solutions, including monkey-patching `emptyQueue()` like this:
```js
PubSubAsyncIterator.prototype.emptyQueue = async function() {
if (this.running) {
this.running = false;
this.pullQueue.forEach(resolve => resolve({ value: undefined, done: true }));
this.pullQueue.length = 0;
this.pushQueue.length = 0;
const subscriptionIds = await this.allSubscribed;
if (subscriptionIds) {
this.unsubscribeAll(subscriptionIds);
}
// This one should make sure new next() calls while we were awaiting and resolved:
this.pullQueue.forEach(resolve => resolve({ value: undefined, done: true }));
}
};
```
~~But interestingly, doing so made other tests in my suite fail for reasons I'm afraid I don't understand right now...~~ Ignore this last part, that failure seemed to be caused by me mis-using Jest's `.resolves` method (forgetting to `await` it).
Contributor guide
Assessment
This issue has not been assessed yet.