Skip to content

Commit 208b0a1

Browse files
committed
AsyncioExecutionMiddleware implementation. Yes, it's that simple!
1 parent a3f9912 commit 208b0a1

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from asyncio import Future, coroutine, iscoroutine, ensure_future
2+
from graphql.core.defer import Deferred
3+
4+
5+
def process_future_result(deferred):
6+
def handle_future_result(future: Future):
7+
exception = future.exception()
8+
if exception:
9+
deferred.errback(exception)
10+
11+
else:
12+
deferred.callback(future.result())
13+
14+
return handle_future_result
15+
16+
17+
class AsyncioExecutionMiddleware(object):
18+
def run_resolve_fn(self, resolver):
19+
result = resolver()
20+
if isinstance(result, Future) or iscoroutine(result):
21+
future = ensure_future(result)
22+
d = Deferred()
23+
future.add_done_callback(process_future_result(d))
24+
return d
25+
26+
return result
27+
28+
def execution_result(self, executor):
29+
future = Future()
30+
result = executor()
31+
assert isinstance(result, Deferred), 'Another middleware has converted the execution result ' \
32+
'away from a Deferred.'
33+
34+
result.add_callback(future.set_result)
35+
result.add_errback(future.set_exception)
36+
37+
return future

tests_py35/core_execution/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__author__ = 'jake'
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from graphql.core.execution.parallel_execution import Executor
2+
from graphql.core.execution.middlewares.AsyncioExecutionMiddleware import AsyncioExecutionMiddleware
3+
from graphql.core.type import (
4+
GraphQLSchema,
5+
GraphQLObjectType,
6+
GraphQLField,
7+
GraphQLString
8+
)
9+
import functools
10+
import asyncio
11+
12+
13+
def run_until_complete(fun):
14+
@functools.wraps(fun)
15+
def wrapper(*args, **kwargs):
16+
coro = fun(*args, **kwargs)
17+
return asyncio.get_event_loop().run_until_complete(coro)
18+
return wrapper
19+
20+
21+
@run_until_complete
22+
async def test_asyncio_py35_executor():
23+
doc = 'query Example { a, b }'
24+
25+
async def resolver(context, *_):
26+
await asyncio.sleep(0.001)
27+
return 'hey'
28+
29+
async def resolver_2(context, *_):
30+
await asyncio.sleep(0.003)
31+
return 'hey2'
32+
33+
Type = GraphQLObjectType('Type', {
34+
'a': GraphQLField(GraphQLString, resolver=resolver),
35+
'b': GraphQLField(GraphQLString, resolver=resolver_2)
36+
})
37+
38+
executor = Executor(GraphQLSchema(Type), [AsyncioExecutionMiddleware()])
39+
result = await executor.execute(doc)
40+
assert not result.errors
41+
assert result.data == {'a': 'hey', 'b': 'hey2'}

0 commit comments

Comments
 (0)