syrusakbary / promise

Ultra-performant Promise implementation in Python
MIT License
362 stars 76 forks source link

call() missing 1 required positional argument: 'fn' when using the AsyncioScheduler #46

Closed mandx closed 7 years ago

mandx commented 7 years ago

For this small (but complete) server code, every schema-related request gets stuck indefinitely (the GraphiQL UI loads fine in all cases):

from aiohttp import web
from aiohttp_graphql import GraphQLView
from graphene import relay
from graphql.execution.executors.asyncio import AsyncioExecutor
from promise import set_default_scheduler
from promise.schedulers.asyncio import AsyncioScheduler
import graphene

class Viewer(graphene.ObjectType, interfaces=(relay.Node,)):
    hello = graphene.String()

    def resolve_hello(self, info):
        return 'Hello!'

class Query(graphene.ObjectType):
    viewer = graphene.Field(Viewer)

    def resolve_viewer(self, info):
        return Viewer()

Schema = graphene.Schema(query=Query)

set_default_scheduler(AsyncioScheduler)

app = web.Application()
GraphQLView.attach(app, schema=Schema, graphiql=True, executor=AsyncioExecutor())
web.run_app(app, host='0.0.0.0', port=8000)

If we only remove the executor parameter from the GraphQLView.attach call, we get this error (as the JSON body)

{"errors":[{"message":"call() missing 1 required positional argument: 'fn'"}]}

Which I was able to track it down (I believe) to the method promise.async_.Async.queue_tick, specifically this call self.schedule.call(self.drain_queues) (line 120 at the moment).

And if we don't set a promise scheduler, then it does works, when omitting the executor param, and also when passing AsyncioExecutor to it.

This is causing some really weird behavior (specially the getting stuck part) specially when using dataloaders, which is understandable because they rely heavily on promises.

Versions (this is inside a virtual environment generated using python3 -m venv .env, where python3 is coming from Ubuntu 17.10):

$ python3 --version                                                                                                                                                       
Python 3.6.3
$ pip freeze
aiohttp==2.3.2
aiohttp-graphql==1.0.0
async-timeout==2.0.0
chardet==3.0.4
graphene==2.0
graphql-core==2.0
graphql-relay==0.4.5
graphql-server-core==1.0.dev20170322001
multidict==3.3.2
pkg-resources==0.0.0
promise==2.1
pytest-runner==3.0
Rx==1.6.0
six==1.11.0
typing==3.6.2
yarl==0.14.0
mandx commented 7 years ago

Nevermind, this is on me; I was setting the scheduler with a reference to the class:

set_default_scheduler(AsyncioScheduler)

but it has to be a reference to an instance.

set_default_scheduler(AsyncioScheduler())