Discussion: decoupling async data loading from async graph resolution
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Cần làm rõ
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- graphql, python
- Lĩnh vực
- api, backend-api-design
Hướng nghiên cứu
Bắt đầu với ví dụ asyncio main() và lệnh gọi graphql(schema, query, context_value=context). Theo dõi cách các resolver async EStopHMI và JogHMI được lập lịch cũng như cách awaitable của chúng được xử lý. Issue này đang tìm kiếm một thiết kế tách biệt việc phát hiện dữ liệu lá, việc lấy dữ liệu và việc phân giải kết quả cuối cùng; không có tệp triển khai hoặc bài kiểm thử cụ thể nào được nêu tên.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
TLDR: I would like graph-core to tell me what "leaf" nodes from my query need returned. Allow me to fetch the data through whatever method I deem efficient. Then I would like graph-core to take care of returning the data. The current asyncio implementation, seems to fundamentally not work for this.
I've been digging in deep on a graphql-core build recently and have stumbled across this interesting problem. If I've missed a key feature of the library here, than please point it out.
To me, the ideal way to use the core library is to:
- Use graph-core to decide what data to retrieve.
- Use a separate data loading engine to read the data.
- Use graph-core to return the data.
Its interesting to see where this problem fits in as either a graphe-core-3 issue, needing a feature, or a graphql issue. The essential catch is this, it's very hard to determine when the graph-core resolution has finished deciding what leaves from the graph need fetched. Here's an example to illustrate the point.
##########################################################
## TEST GRAPHE SCHEMA BASED ON ASYNCIO ######################
##########################################################
from graphql import (
GraphQLBoolean, graphql, GraphQLSchema, GraphQLObjectType, GraphQLField, GraphQLString)
import logging
import asyncio
_logger = logging.getLogger('GrapheneDeferralTest')
_logger.setLevel('DEBUG')
query = """
{
ioHMIControls {
EStopHMI,
JogHMI,
}
}
"""
async def resolve_EStopHMI(parent, info):
_id = '_EStopHMI_id'
info.context['node_ids'][_id] = None
await info.context['awaitable']
return info.context['node_ids'][_id]
EStopHMI = GraphQLField(
GraphQLBoolean,
resolve=resolve_EStopHMI
)
async def resolve_JogHMI(parent, info):
_id = '_JogHMI_id'
info.context['node_ids'][_id] = None
await info.context['awaitable']
return info.context['node_ids'][_id]
JogHMI = GraphQLField(
GraphQLBoolean,
resolve=resolve_EStopHMI
)
def resolve_ioHMIControls(parent, info):
return ioHMIControls
ioHMIControls = GraphQLObjectType(
name='ioHMIControls',
fields={
'EStopHMI': EStopHMI,
'JogHMI':JogHMI,
}
)
def resolve_GlobalVars(parent, info):
return GlobalVars
GlobalVars = GraphQLObjectType(
name='GlobalVars',
fields={
'ioHMIControls': GraphQLField(ioHMIControls, resolve=resolve_ioHMIControls)
}
)
async def simulate_fetch_data(_ids):
print(_ids)
await asyncio.sleep(1)
return {k:True for k in _ids.keys()}
async def main():
# Objective:
# 1. Have graph determine what data I need by partially resolving
# 2. Pause graph resolution.
# 3. Collect data into a `data_loader` object.
# 4. Retrieve data via `data_loader` object.
# 5. Resume graph resolution with loaded data.
# 3. collect ids of data fields into a dict
_ids = {}
#2. pause graph resolution by awaitn a future
future = asyncio.Future()
context = {
'node_ids': _ids,
'awaitable': future,
}
schema = GraphQLSchema(query=GlobalVars)
# 1. Determine WHAT data to return
resove_graph_task = asyncio.create_task(graphql(schema, query, context_value=context))
# ?
# There is no way to detect that resolve_graph_task
# has finished fillin _ids dict with id values.
# 4. Fetch the data
fetch_data_task = asyncio.create_task(simulate_fetch_data(_ids))
# ?
# This await doesn't work in this order or any order
# becaus of the interdependancy of both tasks, coupled with
# the mechanics of asyncio.
await fetch_data_task
# 5. Resume graph resolution with retrieved data.
future.set_result(0)
# ?
# return the data from the graph, as a graph result.
# problem, is that the data is not there due to
# interdependancy between await tasks.
result = await resove_graph_task
print(result)
if __name__ == '__main__':
asyncio.run(main())
Results
{}
ExecutionResult(data={'ioHMIControls': {'EStopHMI': None, 'JogHMI': None}}, errors=None)
The example is a little long, but I wanted it to be sufficiently complex. The gist is that there is no way in the current asyncio implementation to determine that: all resolvers have been reached.
Looking at the implementations we could use some advanced event systems to manage this, but it would be a bit of work. Another possible solution could be to allow resolvers to return coroutines and put off type checking till those coroutines are themselves resolved. I think, this may be the most elegant method.
Thoughts?
- Ngôn ngữ chính
- Python
- Star
- 531
- Fork
- 147
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
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
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của graphql-python/graphql-core
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 50/100
graphql-python/graphql-core#272 · 1 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
graphql-python/graphql-core#269 · 1 bình luận ·
-
Publish a major version Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
graphql-python/graphql-core#267 · 1 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
graphql-python/graphql-core#257 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
graphql-python/graphql-core#247 · 8 bình luận ·
Tất cả issue của graphql-python/graphql-core
Issue tương tự
-
essnmx good first issue
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 95/100
-
[Feature] 奇物选择添加优先级 Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
syfoud/Simulated_Scepter#174 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Giskard-AI/giskard-oss#2840 · 1 bình luận ·
-
A claim comment carrying the issue number is silently declined while the workflow reports success Đang mởarea: repo bug perceived difficulty: 2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
yeti-platform/yeti#1380 ·