graphql-python / graphql-python/flask-graphql

Poor interaction with threads (python 2.7)

Đang mở
#43 3 bình luận 1 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Python
Star
1.3k
Fork
139
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

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]))
```

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.