Skip to content

Commit f20ce04

Browse files
committed
Introduce @stream
1 parent 165f62f commit f20ce04

File tree

1 file changed

+94
-7
lines changed

1 file changed

+94
-7
lines changed

spec/Section 6 -- Execution.md

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,22 @@ serial):
545545
- Let {hasNext} be {true}.
546546
- Let {update} be an unordered map consisting of {errors}, {data},
547547
{pending}, and {hasNext}.
548+
- Otherwise, if {result} incrementally completes a Stream:
549+
- Let {stream}, {items}, {errors}, {newPendingResults}, and {futures} be
550+
the corresponding entries on {result}.
551+
- Let {id} be the entry on {ids} for {stream}.
552+
- If {items} is not defined or is {null}:
553+
- Let {completedEntry} be an unordered map containing {id}.
554+
- If {items} is {null}, set the corresponding entry on {completedEntry}
555+
to {errors}.
556+
- Append {completedEntry} to {completed}.
557+
- Remove {stream} from {pendingResults}.
558+
- Let {update} be an unordered map consisting of {completed}.
559+
- Otherwise:
560+
- Let {incrementalEntry} be an unordered map containing {id}, {items},
561+
and {errors}.
562+
- Append {incrementalEntry} to {incremental}.
563+
- Let {update} be an unordered map consisting of {incremental}.
548564
- Otherwise, {result} incrementally completes Deferred Fragments:
549565
- Let {deferredFragments} be those Deferred Fragments.
550566
- If {data} is {null}:
@@ -582,13 +598,19 @@ serial):
582598
- Append {completedEntry} to {completed}.
583599
- Remove {deferredFragment} from {pendingResults}.
584600
- For each {newPendingResult} in {newPendingResults}:
585-
- Let {parent} be the corresponding entry on {newPendingResult}.
586-
- Add {newPendingResult} to {pendingResults} as a new node directed from
587-
{parent}, if it is also present in {pendingResults}.
601+
- If {newPendingResult} represents a Stream:
602+
- Add {newPendingResult} to {pendingResults}.
603+
- Otherwise:
604+
- Let {parent} be the corresponding entry on {newPendingResult}.
605+
- Add {newPendingResult} to {pendingResults} as a new node directed from
606+
{parent}, if it is also present in {pendingResults}.
588607
- For each {future} of {futures}:
589-
- Let {deferredFragments} be the Deferred Fragments completed by {future}.
590-
- Add {future} to {pendingResults} as a node directed from each of
591-
{deferredFragments}.
608+
- If {future} incrementally completes a Stream:
609+
- If {future} has not been initiated, initiate {future}.
610+
- Otherwise:
611+
- Let {deferredFragments} be the Deferred Fragments completed by {future}.
612+
- Add {future} to {pendingResults} as a node directed from each of
613+
{deferredFragments}.
592614
- While any root nodes in {pendingResults} representing Deferred Fragments
593615
contain no direct child Futures, remove those root nodes from
594616
{pendingResults}.
@@ -1025,8 +1047,37 @@ pendingResults, path, deferUsageSet, deferMap):
10251047
- Initialize {newPendingResults} and {futures} to empty lists.
10261048
- Let {fieldDetails} be the first entry in {fieldDetailsList}.
10271049
- Let {field} be the corresponding entry on {fieldDetails}.
1050+
- If {field} provides the directive `@stream` and its {if} argument is not
1051+
{false} and is not a variable in {variableValues} with the value {false} and
1052+
{innerType} is the outermost inner type of the list type defined for
1053+
{fieldDetailsList}:
1054+
- Let {streamDirective} be that directive.
1055+
- If this execution is for a subscription operation, raise a _field error_.
1056+
- Let {initialCount} be the value or variable provided to {streamDirective}'s
1057+
{initialCount} argument.
1058+
- If {initialCount} is less than zero, raise a _field error_.
1059+
- Let {label} be the value or variable provided to {streamDirective}'s {label}
1060+
argument.
1061+
- Let {iterator} be an iterator for {result}.
10281062
- Let {items} be an empty list.
1029-
- For each {resultItem} of {result}:
1063+
- Let {index} be zero.
1064+
- While {result} is not closed:
1065+
- If {streamDirective} is defined and {index} is greater than or equal to
1066+
{initialCount}:
1067+
- Let {stream} be an unordered map containing {path} and {label}.
1068+
- Let {streamFieldDetails} be the result of
1069+
{GetStreamFieldDetailsList(fieldDetailsList)}.
1070+
- Let {future} represent the future execution of {ExecuteStreamField(stream,
1071+
iterator, streamFieldDetailsList, index, innerType, variableValues,
1072+
pendingResults)}.
1073+
- If early execution is desired, following any implementation specific
1074+
deferral, whichever occurs first.
1075+
- Append {future} to {futures}.
1076+
- Return {items}, {newPendingResults}, and {futures}.
1077+
- Wait for the next item from {result} via the {iterator}.
1078+
- If an item is not retrieved because of an error, raise a _field error_.
1079+
- Let {item} be the item retrieved from {result}.
1080+
- Let {itemPath} be {path} with {index} appended.
10301081
- Let {completedItem}, {itemNewPendingResults}, and {itemFutures} be the
10311082
result of calling {CompleteValue(innerType, fieldDetailsList, item,
10321083
variableValues, pendingResults, itemPath)}.
@@ -1035,6 +1086,42 @@ pendingResults, path, deferUsageSet, deferMap):
10351086
{newPendingResults}, and {futures}, respectively.
10361087
- Return {items}, {newPendingResults}, and {futures}.
10371088

1089+
GetStreamFieldDetailsList(fieldDetailsList):
1090+
1091+
- Let {streamFields} be an empty list.
1092+
- For each {fieldDetails} in {fieldDetailsList}:
1093+
- Let {field} be the corresponding entry on {fieldDetails}.
1094+
- Let {newFieldDetails} be a new Field Details record created from {field}.
1095+
- Append {newFieldDetails} to {streamFields}.
1096+
- Return {streamFields}.
1097+
1098+
#### Execute Stream Field
1099+
1100+
ExecuteStreamField(stream, iterator, fieldDetailsList, index, innerType,
1101+
variableValues, pendingResults):
1102+
1103+
- Let {path} be the corresponding entry on {stream}.
1104+
- Let {itemPath} be {path} with {index} appended.
1105+
- Wait for the next item from {iterator}.
1106+
- If {iterator} is closed, complete this data stream and return.
1107+
- Let {item} be the next item retrieved via {iterator}.
1108+
- Let {nextIndex} be {index} plus one.
1109+
- Let {completedItem}, {newPendingResults}, and {futures} be the result of
1110+
{CompleteValue(innerType, fields, item, variableValues, itemPath)}.
1111+
- Initialize {items} to an empty list.
1112+
- Append {completedItem} to {items}.
1113+
- Let {errors} be the list of all _field error_ raised while completing the
1114+
item.
1115+
- Let {future} represent the future execution of {ExecuteStreamField(stream,
1116+
path, iterator, fieldDetailsList, nextIndex, innerType, variableValues,
1117+
pendingResults)}.
1118+
- If early execution of streamed fields is desired:
1119+
- Following any implementation specific deferral of further execution,
1120+
initiate {future}.
1121+
- Append {future} to {futures}.
1122+
- Return an unordered map containing {items}, {errors}, {newPendingResults}, and
1123+
{futures}.
1124+
10381125
**Coercing Results**
10391126

10401127
The primary purpose of value completion is to ensure that the values returned by

0 commit comments

Comments
 (0)