From 9e13d280816bf749dc502ba7965d01627ffc9946 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Thu, 9 Nov 2023 12:56:54 +0200 Subject: [PATCH] deduplicate delivery of grouped field sets contained by parent/child incremental results deduplication of delivery of grouped field sets contained by parent/child incremental results can be performed during the field analysis stage as parent results will always be delivered prior to child results. Parallel deferred fragments may be emitted in any order, and so we need to check at runtime whether grouped field sets have been previously delivered. Child fragments, however, need never include a reference to any grouped field sets contained by the parent, precluding even the need for a check. This is a small optimization at runtime requiring maintaining additional metadata during the field analysis portion. --- spec/Section 6 -- Execution.md | 122 ++++++++++++++++++++++++++------- 1 file changed, 96 insertions(+), 26 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 3bc9d7a94..9dded7c5d 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -857,10 +857,15 @@ and so that fields are grouped according to the set of deferred fragments that include them. Information derived from the presence of a `@defer` directive on a fragment is -returned as a Defer Usage record, unique to the label, a structure containing -only: +returned as a Defer Usage record, unique to the label, a structure containing: - {label}: value of the corresponding argument to the `@defer` directive. +- {ancestors}: a list, where the first entry is the parent Defer Usage record + corresponding to the deferred fragment enclosing this deferred fragment and + the remaining entries are the values included within the {ancestors} entry of + that parent Defer Usage record, or, if this Defer Usage record is deferred + directly by the initial result, a list containing the single value + {undefined}. A Field Group record is a structure containing: @@ -943,7 +948,13 @@ parentTarget, newTarget): - If {deferDirective} is defined: - Let {label} be the value or the variable to {deferDirective}'s {label} argument. - - Let {target} be a new Defer Usage record created from {label}. + - Let {ancestors} be an empty list. + - Append {parentTarget} to {ancestors}. + - If {parentTarget} is defined: + - Let {parentAncestors} be the {ancestor} entry on {parentTarget}. + - Append all items in {parentAncestors} to {ancestors}. + - Let {target} be a new Defer Usage record created from {label} and + {ancestors}. - Append {target} to {newDeferUsages}. - Otherwise: - Let {target} be {newTarget}. @@ -978,7 +989,13 @@ parentTarget, newTarget): - If {deferDirective} is defined: - Let {label} be the value or the variable to {deferDirective}'s {label} argument. - - Let {target} be a new Defer Usage record created from {label}. + - Let {ancestors} be an empty list. + - Append {parentTarget} to {ancestors}. + - If {parentTarget} is defined: + - Let {parentAncestors} be {ancestor} on {parentTarget}. + - Append all items in {parentAncestors} to {ancestors}. + - Let {target} be a new Defer Usage record created from {label} and + {ancestors}. - Append {target} to {newDeferUsages}. - Otherwise: - Let {target} be {newTarget}. @@ -1033,31 +1050,84 @@ BuildGroupedFieldSets(fieldsByTarget, targetsByKey, parentTargets) - Let {fieldDetails} be a new Field Details record created from {node} and {target}. - Append {fieldDetails} to the {fields} entry on {fieldGroup}. - - Continue to the next entry in {targetsByKey}. - - For each {key} in {groupDetailsMap}: - - If {IsSameSet(targets, key)} is {true}: - - Let {details} be the map in {groupDetailsMap} for {targets}. - - Let {newGroupedFieldSet} be the corresponding entry on {details}. - - If {details} is not defined: - - Initialize {newGroupedFieldSet} to an empty ordered map. - - Initialize {shouldInitiateDefer} to {false}. +- Initialize {groupDetailsMap} to an empty unordered map. +- For each {maskingTargets} and {targetSetDetails} in {targetSetDetailsMap}: + - Initialize {newGroupedFieldSet} to an empty ordered map. + - Let {keys} be the corresponding entry on {targetSetDetails}. + - Let {orderedResponseKeys} be the result of + {GetOrderedResponseKeys(maskingTargets, remainingFieldsByTarget)}. + - For each {responseKey} in {orderedResponseKeys}: + - If {keys} does not contain {responseKey}, continue to the next member of + {orderedResponseKeys}. + - Let {fieldGroup} be the Field Group record in {newGroupedFieldSet} for + {responseKey}; if no such record exists, create a new such record from the + empty list {fields} and the set of {parentTargets}. + - Let {targets} be the entry in {targetsByKeys} for {responseKey}. - For each {target} in {targets}: + - Let {remainingFieldsForTarget} be the entry in {remainingFieldsByTarget} + for {target}. + - Let {nodes} be the list in {remainingFieldsByTarget} for {responseKey}. + - Remove the entry for {responseKey} from {remainingFieldsByTarget}. + - For each {node} of {nodes}: + - Let {fieldDetails} be a new Field Details record created from {node} + and {target}. + - Append {fieldDetails} to the {fields} entry on {fieldGroup}. + - Let {shouldInitiateDefer} be the corresponding entry on {targetSetDetails}. + - Initialize {details} to an empty unordered map. + - Set the entry for {groupedFieldSet} in {details} to {newGroupedFieldSet}. + - Set the corresponding entry in {details} to {shouldInitiateDefer}. + - Set the entry for {maskingTargets} in {groupDetailsMap} to {details}. +- Return {groupedFieldSet} and {groupDetailsMap}. + +Note: entries are always added to Grouped Field Set records in the order in +which they appear for the first target. Field order for deferred grouped field +sets never alters the field order for the parent. + +GetOrderedResponseKeys(targets, fieldsByTarget): + +- Let {firstTarget} be the first entry in {targets}. +- Assert that {firstTarget} is defined. +- Let {firstFields} be the entry for {firstTarget} in {fieldsByTarget}. +- Assert that {firstFields} is defined. +- Let {responseKeys} be the keys of {firstFields}. +- Return {responseKeys}. + +GetTargetSetDetails(targetsByKey, parentTargets): + +- Initialize {keysWithParentTargets} to the empty set. +- Initialize {targetSetDetailsMap} to an empty unordered map. +- For each {responseKey} and {targets} in {targetsByKey}: + - Initialize {maskingTargets} to an empty set. + - For each {target} in {targets}: + - If {target} is not defined: + - Add {target} to {maskingTargets}. + - Continue to the next entry in {targets}. + - Let {ancestors} be the corresponding entry on {target}. + - For each {ancestor} of {ancestors}: + - If {targets} contains {ancestor}, continue to the next member of + {targets}. + - Add {target} to {maskingTargets}. + - If {IsSameSet(maskingTargets, parentTargets)} is {true}: + - Append {responseKey} to {keysWithParentTargets}. + - Continue to the next entry in {targetsByKey}. + - For each {key} in {targetSetDetailsMap}: + - If {IsSameSet(maskingTargets, key)} is {true}, let {targetSetDetails} be + the map in {targetSetDetailsMap} for {maskingTargets}. + - If {targetSetDetails} is defined: + - Let {keys} be the corresponding entry on {targetSetDetails}. + - Add {responseKey} to {keys}. + - Otherwise: + - Initialize {keys} to the empty set. + - Add {responseKey} to {keys}. + - Let {shouldInitiateDefer} be {false}. + - For each {target} in {maskingTargets}: - If {parentTargets} does not contain {target}: - Set {shouldInitiateDefer} equal to {true}. - - Initialize {details} to an empty unordered map consisting of - {newGroupedFieldSet} and {shouldInitiateDefer}. - - Set the entry for {targets} in {groupDetailsMap} to {groupDetails}. - - Let {fieldGroup} be the Field Group record in {newGroupedFieldSet} for - {responseKey}; if no such record exists, create a new such record from the - empty list {fields} and the set of {parentTargets}. - - For each {target} in {targets}: - - Let {fields} be the entry in {fieldsByTarget} for {target}. - - Let {nodes} be the list in {fields} for {responseKey}. - - For each {node} of {nodes}: - - Let {fieldDetails} be a new Field Details record created from {node} and - {target}. - - Append {fieldDetails} to the {fields} entry on {fieldGroup}. -- Return {groupedFieldSet} and {groupDetailsMap}. + - Create {newTargetSetDetails} as an map containing {keys} and + {shouldInitiateDefer}. + - Set the entry in {targetSetDetailsMap} for {maskingTargets} to + {newTargetSetDetails}. +- Return {keysWithParentTargets} and {targetSetDetailsMap}. IsSameSet(setA, setB):