Skip to content

Commit 677f1a7

Browse files
committed
do not initiate multiple streams at the same path
1 parent 2a628a1 commit 677f1a7

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

spec/Section 6 -- Execution.md

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -134,21 +134,22 @@ ExecuteQuery(query, schema, variableValues, initialValue):
134134

135135
- Let {subsequentPayloads} be an empty list.
136136
- Initialize {branches} to the empty set.
137+
- Initialize {streams} to the empty set.
137138
- Let {queryType} be the root Query type in {schema}.
138139
- Assert: {queryType} is an Object type.
139140
- Let {selectionSet} be the top level Selection Set in {query}.
140141
- Let {groupedFieldSet} and {newDeferDepth} be the result of
141142
{CollectRootFields(queryType, selectionSet, variableValues)}.
142143
- Let {data} be the result of running {ExecuteGroupedFieldSet(groupedFieldSet,
143-
queryType, initialValue, variableValues, subsequentPayloads, branches)}
144-
_normally_ (allowing parallelization).
144+
queryType, initialValue, variableValues, subsequentPayloads, branches,
145+
streams)} _normally_ (allowing parallelization).
145146
- Let {errors} be the list of all _field error_ raised while executing the
146147
selection set.
147148
- If {newDeferDepth} is defined and {ShouldBranch(branches, groupedFieldSet,
148149
path)} is {true}:
149150
- Call {ExecuteDeferredFragment(objectType, objectValue, groupedFieldSet,
150151
path, newDeferDepth, variableValues, asyncRecord, subsequentPayloads,
151-
branches)}
152+
branches, streams)}
152153
- If {subsequentPayloads} is empty:
153154
- Return an unordered map containing {data} and {errors}.
154155
- If {subsequentPayloads} is not empty:
@@ -177,21 +178,22 @@ ExecuteMutation(mutation, schema, variableValues, initialValue):
177178

178179
- Let {subsequentPayloads} be an empty list.
179180
- Initialize {branches} to the empty set.
181+
- Initialize {streams} to the empty set.
180182
- Let {mutationType} be the root Mutation type in {schema}.
181183
- Assert: {mutationType} is an Object type.
182184
- Let {selectionSet} be the top level Selection Set in {mutation}.
183185
- Let {groupedFieldSet} and {newDeferDepth} be the result of
184186
{CollectRootFields(queryType, selectionSet, variableValues)}.
185187
- Let {data} be the result of running {ExecuteGroupedFieldSet(groupedFieldSet,
186-
mutationType, initialValue, variableValues, subsequentPayloads, branches)}
187-
_serially_.
188+
mutationType, initialValue, variableValues, subsequentPayloads, branches,
189+
streams)} _serially_.
188190
- Let {errors} be the list of all _field error_ raised while executing the
189191
selection set.
190192
- If {newDeferDepth} is defined and {ShouldBranch(branches, groupedFieldSet,
191193
path)} is {true}:
192194
- Call {ExecuteDeferredFragment(objectType, objectValue,
193195
deferredGroupFieldSet, path, newDeferDepth, variableValues, asyncRecord,
194-
subsequentPayloads, branches)}
196+
subsequentPayloads, branches, streams)}
195197
- If {subsequentPayloads} is empty:
196198
- Return an unordered map containing {data} and {errors}.
197199
- If {subsequentPayloads} is not empty:
@@ -429,7 +431,7 @@ Each represented field in the grouped field set produces an entry into a
429431
response map.
430432

431433
ExecuteGroupedFieldSet(groupedFieldSet, objectType, objectValue, variableValues,
432-
path, subsequentPayloads, branches, asyncRecord):
434+
path, subsequentPayloads, branches, streams, asyncRecord):
433435

434436
- If {path} is not provided, initialize it to an empty list, unique for this
435437
execution.
@@ -445,7 +447,7 @@ path, subsequentPayloads, branches, asyncRecord):
445447
- If {fieldType} is defined:
446448
- If {ShouldExecute(fieldGroup, asyncRecord)} is {true}:
447449
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
448-
fieldGroup, variableValues, path, subsequentPayloads, branches,
450+
fieldGroup, variableValues, path, subsequentPayloads, branches, streams,
449451
asyncRecord)}.
450452
- Set {responseValue} as the value for {responseKey} in {resultMap}.
451453
- Return {resultMap}.
@@ -807,7 +809,8 @@ All Async Payload Records are structures containing:
807809
#### Execute Deferred Fragment
808810

809811
ExecuteDeferredFragment(objectType, objectValue, groupedFieldSet, path,
810-
deferDepth, variableValues, parentRecord, subsequentPayloads, branches):
812+
deferDepth, variableValues, parentRecord, subsequentPayloads, branches,
813+
streams):
811814

812815
- Let {deferRecord} be an async payload record created from {path} and
813816
{deferDepth}.
@@ -825,7 +828,7 @@ deferDepth, variableValues, parentRecord, subsequentPayloads, branches):
825828
- If {fieldType} is defined:
826829
- Let {responseValue} be {ExecuteField(objectType, objectValue, fieldType,
827830
fieldGroup, variableValues, path, subsequentPayloads, asyncRecord,
828-
branches)}.
831+
branches, streams)}.
829832
- Set {responseValue} as the value for {responseKey} in {resultMap}.
830833
- Append any encountered field errors to {errors}.
831834
- If {parentRecord} is defined:
@@ -890,7 +893,7 @@ finally completes that value either by recursively executing another selection
890893
set or coercing a scalar value.
891894

892895
ExecuteField(objectType, objectValue, fieldType, fieldGroup, variableValues,
893-
path, subsequentPayloads, branches, asyncRecord):
896+
path, subsequentPayloads, branches, streams, asyncRecord):
894897

895898
- Let {taggedField} be the value of the first entry in {fieldGroup}.
896899
- Let {field} be the corresponding entry within {taggedField}.
@@ -903,7 +906,7 @@ path, subsequentPayloads, branches, asyncRecord):
903906
argumentValues)}.
904907
- Let {result} be the result of calling {CompleteValue(fieldType, fieldGroup,
905908
resolvedValue, variableValues, fieldPath, subsequentPayloads, branches,
906-
asyncRecord)}.
909+
streams, asyncRecord)}.
907910
- Return {result}.
908911

909912
### Coercing Field Arguments
@@ -1007,7 +1010,7 @@ yielded items satisfies `initialCount` specified on the `@stream` directive.
10071010
#### Execute Stream Field
10081011

10091012
ExecuteStreamField(iterator, index, fieldGroup, innerType, path, deferDepth,
1010-
parentRecord, variableValues, subsequentPayloads, branches):
1013+
parentRecord, variableValues, subsequentPayloads, branches, streams):
10111014

10121015
- If {parentRecord} is defined:
10131016
- Let {deferDepth} be equal to the corresponding entry on {asyncRecord}.
@@ -1028,12 +1031,12 @@ parentRecord, variableValues, subsequentPayloads, branches):
10281031
- Otherwise:
10291032
- Let {item} be the item retrieved from {iterator}.
10301033
- Let {data} be the result of calling {CompleteValue(innerType, fieldGroup,
1031-
item, variableValues, itemPath, subsequentPayloads, branches,
1034+
item, variableValues, itemPath, subsequentPayloads, branches, streams,
10321035
parentRecord)}.
10331036
- Append any encountered field errors to {errors}.
10341037
- Increment {index}.
10351038
- Call {ExecuteStreamField(iterator, index, fieldGroup, innerType, path,
1036-
streamRecord, variableValues, subsequentPayloads, branches)}.
1039+
streamRecord, variableValues, subsequentPayloads, branches, streams)}.
10371040
- If a field error was raised, causing a {null} to be propagated to {data},
10381041
and {innerType} is a Non-Nullable type:
10391042
- Add an entry to {payload} named `items` with the value {null}.
@@ -1050,7 +1053,7 @@ parentRecord, variableValues, subsequentPayloads, branches):
10501053
- Append {streamRecord} to {subsequentPayloads}.
10511054

10521055
CompleteValue(fieldType, fieldGroup, result, variableValues, path,
1053-
subsequentPayloads, asyncRecord, branches):
1056+
subsequentPayloads, asyncRecord, branches, streams):
10541057

10551058
- If the {fieldType} is a Non-Null type:
10561059
- Let {innerType} be the inner type of {fieldType}.
@@ -1080,8 +1083,9 @@ subsequentPayloads, asyncRecord, branches):
10801083
- While {result} is not closed:
10811084
- If {streamDirective} is defined and {index} is greater than or equal to
10821085
{initialCount}:
1083-
- Call {ExecuteStreamField(iterator, index, fieldGroup, innerType, path,
1084-
asyncRecord, subsequentPayloads, branches)}.
1086+
- If {ShouldStream(streams, fieldGroup)}:
1087+
- Call {ExecuteStreamField(iterator, index, fieldGroup, innerType, path,
1088+
asyncRecord, subsequentPayloads, branches, streams)}.
10851089
- Return {items}.
10861090
- Otherwise:
10871091
- Wait for the next item from {result} via the {iterator}.
@@ -1091,7 +1095,7 @@ subsequentPayloads, asyncRecord, branches):
10911095
{index} appended.
10921096
- Let {resolvedItem} be the result of calling {CompleteValue(innerType,
10931097
fieldGroup, resultItem, variableValues, itemPath, subsequentPayloads,
1094-
branches, asyncRecord)}.
1098+
branches, streams, asyncRecord)}.
10951099
- Append {resolvedItem} to {items}.
10961100
- Increment {index}.
10971101
- Return {items}.
@@ -1107,12 +1111,12 @@ subsequentPayloads, asyncRecord, branches):
11071111
- Let {resultMap} be the result of evaluating
11081112
{ExecuteGroupedFieldSet(groupedSubfieldSet, deferredGroupedSubfieldsList
11091113
objectType, result, variableValues, path, subsequentPayloads, branches,
1110-
asyncRecord)} _normally_ (allowing for parallelization).
1114+
streams, asyncRecord)} _normally_ (allowing for parallelization).
11111115
- If {newDeferDepth} is defined and {ShouldBranch(branches, groupedFieldSet,
11121116
path)} is {true}:
11131117
- Call {ExecuteDeferredFragment(objectType, objectValue, groupedFieldSet,
11141118
path, newDeferDepth, variableValues, asyncRecord, subsequentPayloads,
1115-
branches)},
1119+
branches, streams)},
11161120
- Return {resultMap}.
11171121

11181122
ShouldBranch(branches, path):
@@ -1121,6 +1125,12 @@ ShouldBranch(branches, path):
11211125
- Add {path} to {branches}.
11221126
- Return {true}.
11231127

1128+
ShouldStream(streams, path):
1129+
1130+
- If {streams} contains {path}, return {false}.
1131+
- Add {path} to {streams}.
1132+
- Return {true}.
1133+
11241134
ShouldExecute(fieldGroup, asyncPayloadRecord):
11251135

11261136
- Let {hasDepth} equal {false}.

0 commit comments

Comments
 (0)