Closed jedwards1211 closed 2 years ago
I have refactored the withFilter
method to operate on AsyncIterable
s rather than AsyncIterator
s.
@jonbudd actually I don't think this is a work in progress anymore...
Although I think asyncIterable
is a better API design, I was wrong that it can be totally safe.
so IMO async iterators still give you quite a nice way to manipulate these things
i think the best way to go is to just have some explicit closeability concept; see what we did in https://github.com/4Catalyzer/graphql-subscription-server/pull/20/files
@taion But who calls that? Don't we depend on https://github.com/apollographql/subscriptions-transport-ws to call return
right now? Would we need to modify that?
the approach we use is:
close
callbackclose
callbacks to call associated with each client subscriptionclose
methods when we tear down the client subscriptionso we just don't use return
at all
Okay, so that would require modifying the transport...
Thanks @jedwards1211 and sorry we didn't get to this sooner. A lot has changed with the codebase since this was opened, and some of these changes are already coming in 3.0. I'll close this off but please open any new PR's (ideally based off of the release-3.0
branch) that you would like to see added. @brainkim is helping maintain this project now as well, so the great conversation you both had in https://github.com/tc39/proposal-async-iteration/issues/126 can continue in this repo.
Side note @brainkim - karma:
By the way, two issues/antipatterns I see from lurking in the GraphQL community related to lazy async iterators, but which I just haven’t really commented on because it might seem too self-promotional and I don’t really use GraphQL ...
😂
As @jquense wisely helped me realize in #143,
pubsub.asyncIterator
is unsafe and could leave dangling event listeners when consumed by 3rd-party code.In general the documentation mistakenly states that GraphQL
subscribe
resolvers must return anAsyncIterator
; rather, they should return anAsyncIterable
, and event listener registration/anything else necessitating cleanup should only be performed when thatAsyncIterable
'sSymbol.asyncIterator
method is actually called, sincefor await
and probably most 3rd-party code is only guaranteed toreturn
the iterator if it ends up starting iteration (i.e. callingSymbol.asyncIterator
).As a solution, I've created a new
pubsub.asyncIterable
method that we should advise people to use. I also madeeventEmitterToAsyncIterator
print a deprecation warning when it's used like anAsyncIterable
(which will happen with the current recommended usage ofpubsub.asyncIterator
).The
withFilter
method still needs to be redesigned to operate onAsyncIterable
s instead ofAsyncIterators
.