graphql-python / graphql-python/flask-graphql

Poor interaction with threads (python 2.7)

Abierto
#43 3 comentarios 1 reacción 0 asignados Ver en GitHub
Lenguaje dominante
Python
Estrellas
1.3k
Forks
139
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

the interaction between this library, graphql-core, and promise appears to allow execution to hop threads especially (only?) when using a middleware and nested resolvers. this is inconsistent with flasks threading model and the ability to access the request/g thread locals

with the attached (very contrived) example, when submitting the query with concurrent requests the requests frequently fail because the key created in get_context doesn't exist on the threadlocal flask.g object in the resolvers. This happens when a thread accesses the promise.async_instance which isn't thread local, and resolves a promise that was created on a different thread.
[query.txt](https://github.com/graphql-python/flask-graphql/files/2014433/query.txt)

```
from flask import Flask
from flask_graphql import GraphQLView

app = Flask(__name__)

import graphene
import threading
import time
from flask import g

def get_user(info):
return g.get(info.context['key'])

class User(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
friend = graphene.Field(lambda: User)
age = graphene.Int()
apple = graphene.String()

@classmethod
def resolve_friend(cls, root, info):
time.sleep(.1)
x = get_user(info)
return User(id=id(root), name=':'.join([x.name, threading.current_thread().name]))

@classmethod
def resolve_age(cls, root, info):
time.sleep(.1)
return 5

@classmethod
def resolve_apple(cls, root, info):
time.sleep(.1)
return "Apple"

class Query(graphene.ObjectType):
me = graphene.Field(User)

def resolve_me(self, info):
time.sleep(.1)
return get_user(info)

schema = graphene.Schema(query=Query)

ahh = {}
def dummy_middleware(next, root, info, **args):
return_value = next(root, info, **args)
return return_value

import random
random.seed()

class TestQLView(GraphQLView):
def get_context(self, request):
# set a random key in g to be used by resolvers
key = str(random.randint(0,50))
name = threading.current_thread().name
user = User(id=key, name=name)
setattr(g, key, user)
return {
'key': key
}

app.add_url_rule('/graphql', view_func=TestQLView.as_view('graphql', schema=schema, graphiql=True, middleware=[dummy_middleware]))
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.