Skip to content

Commit ef478a2

Browse files
authored
fix(incremental): skip all empty subsequent results (#3993)
The publish method checks to see if a subsequent result is empty; this same logic should be employed to suppress pending notices for empty records. This has already been achieved for subsequent results that are children of the initial result, as we generated the pending notices from the list of initially published records. For subsequent results that are children of other subsequent results, we previously generated the pending notice prior to actually publishing. This change integrates the logic: the publishing method itself returns a pending notice as required. This results in a bug-fix for subsequent records of other subsequent records as well as a reduction of code for subsequent results to the initial result.
1 parent 9c90a23 commit ef478a2

File tree

2 files changed

+48
-52
lines changed

2 files changed

+48
-52
lines changed

src/execution/IncrementalPublisher.ts

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -301,25 +301,11 @@ export class IncrementalPublisher {
301301
initialResultRecord: InitialResultRecord,
302302
data: ObjMap<unknown> | null,
303303
): ExecutionResult | ExperimentalIncrementalExecutionResults {
304-
for (const child of initialResultRecord.children) {
305-
if (child.filtered) {
306-
continue;
307-
}
308-
this._publish(child);
309-
}
304+
const pendingSources = this._publish(initialResultRecord.children);
310305

311306
const errors = initialResultRecord.errors;
312307
const initialResult = errors.length === 0 ? { data } : { errors, data };
313-
const pending = this._pending;
314-
if (pending.size > 0) {
315-
const pendingSources = new Set<DeferredFragmentRecord | StreamRecord>();
316-
for (const subsequentResultRecord of pending) {
317-
const pendingSource = isStreamItemsRecord(subsequentResultRecord)
318-
? subsequentResultRecord.streamRecord
319-
: subsequentResultRecord;
320-
pendingSources.add(pendingSource);
321-
}
322-
308+
if (pendingSources.size > 0) {
323309
return {
324310
initialResult: {
325311
...initialResult,
@@ -538,18 +524,7 @@ export class IncrementalPublisher {
538524
const incrementalResults: Array<IncrementalResult> = [];
539525
const completedResults: Array<CompletedResult> = [];
540526
for (const subsequentResultRecord of completedRecords) {
541-
for (const child of subsequentResultRecord.children) {
542-
if (child.filtered) {
543-
continue;
544-
}
545-
const pendingSource = isStreamItemsRecord(child)
546-
? child.streamRecord
547-
: child;
548-
if (!pendingSource.pendingSent) {
549-
newPendingSources.add(pendingSource);
550-
}
551-
this._publish(child);
552-
}
527+
this._publish(subsequentResultRecord.children, newPendingSources);
553528
if (isStreamItemsRecord(subsequentResultRecord)) {
554529
if (subsequentResultRecord.isFinalRecord) {
555530
newPendingSources.delete(subsequentResultRecord.streamRecord);
@@ -613,6 +588,8 @@ export class IncrementalPublisher {
613588
let idWithLongestPath: string | undefined;
614589
for (const deferredFragmentRecord of deferredFragmentRecords) {
615590
const id = deferredFragmentRecord.id;
591+
// TODO: add test
592+
/* c8 ignore next 3 */
616593
if (id === undefined) {
617594
continue;
618595
}
@@ -655,25 +632,51 @@ export class IncrementalPublisher {
655632
return result;
656633
}
657634

658-
private _publish(subsequentResultRecord: SubsequentResultRecord): void {
659-
if (isStreamItemsRecord(subsequentResultRecord)) {
660-
if (subsequentResultRecord.isCompleted) {
635+
private _publish(
636+
subsequentResultRecords: ReadonlySet<SubsequentResultRecord>,
637+
pendingSources = new Set<DeferredFragmentRecord | StreamRecord>(),
638+
): Set<DeferredFragmentRecord | StreamRecord> {
639+
const emptyRecords: Array<SubsequentResultRecord> = [];
640+
641+
for (const subsequentResultRecord of subsequentResultRecords) {
642+
if (subsequentResultRecord.filtered) {
643+
continue;
644+
}
645+
if (isStreamItemsRecord(subsequentResultRecord)) {
646+
if (subsequentResultRecord.isCompleted) {
647+
this._push(subsequentResultRecord);
648+
} else {
649+
this._introduce(subsequentResultRecord);
650+
}
651+
652+
const stream = subsequentResultRecord.streamRecord;
653+
if (!stream.pendingSent) {
654+
pendingSources.add(stream);
655+
}
656+
continue;
657+
}
658+
659+
if (subsequentResultRecord._pending.size > 0) {
660+
this._introduce(subsequentResultRecord);
661+
} else if (
662+
subsequentResultRecord.deferredGroupedFieldSetRecords.size === 0
663+
) {
664+
emptyRecords.push(subsequentResultRecord);
665+
continue;
666+
} else {
661667
this._push(subsequentResultRecord);
662-
return;
663668
}
664669

665-
this._introduce(subsequentResultRecord);
666-
return;
670+
if (!subsequentResultRecord.pendingSent) {
671+
pendingSources.add(subsequentResultRecord);
672+
}
667673
}
668674

669-
if (subsequentResultRecord._pending.size > 0) {
670-
this._introduce(subsequentResultRecord);
671-
} else if (
672-
subsequentResultRecord.deferredGroupedFieldSetRecords.size > 0 ||
673-
subsequentResultRecord.children.size > 0
674-
) {
675-
this._push(subsequentResultRecord);
675+
for (const emptyRecord of emptyRecords) {
676+
this._publish(emptyRecord.children, pendingSources);
676677
}
678+
679+
return pendingSources;
677680
}
678681

679682
private _getChildren(

src/execution/__tests__/defer-test.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,34 +1023,27 @@ describe('Execute: defer directive', () => {
10231023
},
10241024
},
10251025
pending: [
1026-
{ id: '0', path: ['hero'] },
1026+
{ id: '0', path: ['hero', 'nestedObject', 'deeperObject'] },
10271027
{ id: '1', path: ['hero', 'nestedObject', 'deeperObject'] },
10281028
],
10291029
hasNext: true,
10301030
},
10311031
{
1032-
pending: [{ id: '2', path: ['hero', 'nestedObject', 'deeperObject'] }],
10331032
incremental: [
10341033
{
10351034
data: {
10361035
foo: 'foo',
10371036
},
1038-
id: '1',
1037+
id: '0',
10391038
},
1040-
],
1041-
completed: [{ id: '0' }, { id: '1' }],
1042-
hasNext: true,
1043-
},
1044-
{
1045-
incremental: [
10461039
{
10471040
data: {
10481041
bar: 'bar',
10491042
},
1050-
id: '2',
1043+
id: '1',
10511044
},
10521045
],
1053-
completed: [{ id: '2' }],
1046+
completed: [{ id: '0' }, { id: '1' }],
10541047
hasNext: false,
10551048
},
10561049
]);

0 commit comments

Comments
 (0)