Repository navigation
Labels
Description
Product
Hot Chocolate
Version
16.6.7
Link to minimal reproduction
Steps to reproduce
- git clone https://github.com/bbarry/graphql-platform.git && cd graphql-platform
- git checkout feature/pagination-fields-parallel
- Restore the unfixed types (the branch's last commit contains the fix):
git checkout HEAD1 -- src/HotChocolate/Core/src/Types.CursorPagination/ConnectionType.cs "src/HotChocolate/Core/src/Types.OffsetPagination/CollectionSegmentType1.cs" - dotnet test src/HotChocolate/Core/test/Types.CursorPagination.Tests -f net11.0 -- --filter-method "ConnectionTypeTests"
dotnet test src/HotChocolate/Core/test/Types.OffsetPagination.Tests -f net11.0 -- --filter-method "CollectionSegmentTypeTests"
test files:
- https://github.com/bbarry/graphql-platform/blob/feature/pagination-fields-parallel/src/HotChocolate/Core/test/Types.CursorPagination.Tests/ConnectionTypeTests.cs
- https://github.com/bbarry/graphql-platform/blob/feature/pagination-fields-parallel/src/HotChocolate/Core/test/Types.OffsetPagination.Tests/CollectionSegmentTypeTests.cs
What is expected?
Every field of the connection and collection segment types is parallel executable:
pageInfo: True, edges: True, nodes: True, totalCount: True
pageInfo: True, items: True, totalCount: Tru
What is actually happening?
edges, nodes and totalCount (connection) and items and totalCount (collection segment) are
not parallel executable, so their selections get SelectionExecutionStrategy.Serial.
Cause:
- ConnectionType.CreateConfiguration (lines 185, 196, 209 on main) and
CollectionSegmentType (lines 102, 111) create each field with
new ObjectFieldConfiguration(..., pureResolver: ...) { Flags = CoreFieldFlags.X }. - The constructor sets IsParallelExecutable = true, which is a bit in Flags, and the object
initializer then replaces Flags, clearing the bit. - ObjectField only restores it when a pure resolver is compiled ("by definition, fields with
pure resolvers are parallel executable", ObjectField.cs lines 205-209). - That only happens when IsPureContext() holds (line 258): no global field middleware and no
field middleware.
So any schema with global field middleware executes these fields serially.
Relevant log output
ConnectionTypeTests (unfixed):
pageInfo: True
- edges: True
- nodes: True
- totalCount: True
+ edges: False
+ nodes: False
+ totalCount: False
CollectionSegmentTypeTests (unfixed):
- items: True
- totalCount: True
+ items: False
+ totalCount: FalseAdditional context
- Same defect as DataLoader used inside node resolvers do not batch #7635, fixed by Added missing ParallelExecutable flag to node and nodes fields #7661 for the node and nodes fields only. That fix is the
idiom NodeFieldTypeInterceptor still uses (lines 177 and 236):
Flags = CoreFieldFlags.ParallelExecutable | CoreFieldFlags.GlobalIdNodeField - Impact: paged results execute through the serial path. With [UsePaging] + [UseProjection] that includes the internal
_combinedSelectionSetselection that resolves nodes. Combined with Request hangs forever when a serial task's id is reassigned before the scheduler waits for it #10561, this made paged queries hang under concurrent load in our services.
Activity