Description
graphql-core
supports "tagging" a resolver (via core.execution.middlewares.utils
) as a way to signal special handling of the resolver in an ExecutionMiddleware
.
The main example is that we have GeventExecutionMiddleware
. By default, this middleware does nothing when processing resolvers. But when it is given a resolver that is tagged with (@run_in_greenlet
) it will spawn a greenlet to execute the resolver, and allow the executor to continue to resolve other fields concurrently.
From the tests, here's a good example (not using Graphene):
@run_in_greenlet
def resolve_a(context, *_):
gevent.sleep(3)
return 'resolved a'
@run_in_greenlet
def resolve_b(context, *_):
gevent.sleep(3)
return 'resolved b'
Type = GraphQLObjectType('Type', {
'a': GraphQLField(GraphQLString, resolver=resolver),
'b': GraphQLField(GraphQLString, resolver=resolver_2)
})
executor = Executor(GraphQLSchema(Type), [GeventExecutionMiddleware()])
doc = 'query Example { a, b }'
result = executor.execute(doc)
assert result.data == {'a': 'resolved a', 'b': 'resolved b'}
In this example, if each function was not tagged with @run_in_greenlet
, then the execution time would be 6 seconds, as they have to run serially. However, since they are tagged, the middleware will run them concurrently, executing the query in only 3 seconds.