Another asynchronous resolution PR. But using JS-like promises instead of goroutines. #357
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Like everyone else, I'm in need of batching, deduplication, and concurrency in my query execution.
But the other pull requests all look like they utilize goroutine-based approaches. This pull request does not use goroutines. Instead, it works a bit more like the JavaScript reference implementation using a notion of promises. Here's how it works in terms of usage:
Resolvers that can execute asynchronously return a channel. To be explicit, a
graphql.ResolvePromise
. So you might have a loader that creates and returns a newgraphql.ResolvePromise
like so:How does the loader fulfill the promise without a goroutine? When the query execution gets "stuck" and there are no more resolvers that it can invoke, it invokes an "idle handler" to let it know that one or more pending promises need to be fulfilled before it can continue. So your params can now specify a scheduler for your loader like so:
When the handler is invoked, it expects one or more promises to be fulfilled. Afterwards, it'll resume resolving values until it gets stuck again.
So your loader implementation might at a high level do something like this:
And so in this way, you can really control when and how your resolutions happen. And there are no goroutines involved or multithreading concerns. Of course, you can use goroutines if you want to though.