Skip to content

Connection and collection segment fields lose ParallelExecutable when global field middleware is registered #10563

Closed

Description

@bbarry

Product

Hot Chocolate

Version

16.6.7

Link to minimal reproduction

https://github.com/bbarry/graphql-platform/blob/feature/pagination-fields-parallel/src/HotChocolate/Core/test/Types.CursorPagination.Tests/ConnectionTypeTests.cs

Steps to reproduce

  1. git clone https://github.com/bbarry/graphql-platform.git && cd graphql-platform
  2. git checkout feature/pagination-fields-parallel
  3. 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"
  4. 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:

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: False

Additional context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions