Skip to content

Commit 8bfd7f5

Browse files
committed
refactor(incremental): enqueue only released records
1 parent 874e970 commit 8bfd7f5

File tree

3 files changed

+78
-82
lines changed

3 files changed

+78
-82
lines changed

src/execution/IncrementalGraph.ts

Lines changed: 44 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { promiseWithResolvers } from '../jsutils/promiseWithResolvers.js';
44
import type {
55
DeferredFragmentRecord,
66
DeferredGroupedFieldSetRecord,
7-
DeferredGroupedFieldSetResult,
87
IncrementalDataRecord,
98
IncrementalDataRecordResult,
109
ReconcilableDeferredGroupedFieldSetResult,
10+
StreamItemsRecord,
1111
StreamRecord,
1212
SubsequentResultRecord,
1313
} from './types.js';
@@ -16,7 +16,6 @@ import { isDeferredGroupedFieldSetRecord } from './types.js';
1616
interface DeferredFragmentNode {
1717
deferredFragmentRecord: DeferredFragmentRecord;
1818
deferredGroupedFieldSetRecords: Set<DeferredGroupedFieldSetRecord>;
19-
results: Array<DeferredGroupedFieldSetResult>;
2019
reconcilableResults: Set<ReconcilableDeferredGroupedFieldSetResult>;
2120
children: Array<DeferredFragmentNode>;
2221
}
@@ -46,6 +45,7 @@ export class IncrementalGraph {
4645
>;
4746

4847
private _newPending: Set<SubsequentResultNode>;
48+
private _newIncrementalDataRecords: Set<IncrementalDataRecord>;
4949
private _completedQueue: Array<IncrementalDataRecordResult>;
5050
private _nextQueue: Array<
5151
(iterable: IteratorResult<Iterable<IncrementalDataRecordResult>>) => void
@@ -54,6 +54,7 @@ export class IncrementalGraph {
5454
constructor() {
5555
this._pending = new Set();
5656
this._deferredFragmentNodes = new Map();
57+
this._newIncrementalDataRecords = new Set();
5758
this._newPending = new Set();
5859
this._completedQueue = [];
5960
this._nextQueue = [];
@@ -64,41 +65,9 @@ export class IncrementalGraph {
6465
): void {
6566
for (const incrementalDataRecord of incrementalDataRecords) {
6667
if (isDeferredGroupedFieldSetRecord(incrementalDataRecord)) {
67-
for (const deferredFragmentRecord of incrementalDataRecord.deferredFragmentRecords) {
68-
const deferredFragmentNode = this._addDeferredFragmentNode(
69-
deferredFragmentRecord,
70-
);
71-
deferredFragmentNode.deferredGroupedFieldSetRecords.add(
72-
incrementalDataRecord,
73-
);
74-
}
75-
76-
const result = incrementalDataRecord.result;
77-
if (isPromise(result)) {
78-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
79-
result.then((resolved) => {
80-
this._enqueueCompletedDeferredGroupedFieldSet(resolved);
81-
});
82-
} else {
83-
this._enqueueCompletedDeferredGroupedFieldSet(result);
84-
}
85-
86-
continue;
87-
}
88-
89-
const streamRecord = incrementalDataRecord.streamRecord;
90-
if (streamRecord.id === undefined) {
91-
this._newPending.add(streamRecord);
92-
}
93-
94-
const result = incrementalDataRecord.result;
95-
if (isPromise(result)) {
96-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
97-
result.then((resolved) => {
98-
this._enqueue(resolved);
99-
});
68+
this._addDeferredGroupedFieldSetRecord(incrementalDataRecord);
10069
} else {
101-
this._enqueue(result);
70+
this._addStreamItemsRecord(incrementalDataRecord);
10271
}
10372
}
10473
}
@@ -127,6 +96,9 @@ export class IncrementalGraph {
12796
this._pending.add(node);
12897
newPending.push(node);
12998
} else if (node.deferredGroupedFieldSetRecords.size > 0) {
99+
for (const deferredGroupedFieldSetNode of node.deferredGroupedFieldSetRecords) {
100+
this._newIncrementalDataRecords.add(deferredGroupedFieldSetNode);
101+
}
130102
this._pending.add(node);
131103
newPending.push(node.deferredFragmentRecord);
132104
} else {
@@ -136,6 +108,18 @@ export class IncrementalGraph {
136108
}
137109
}
138110
this._newPending.clear();
111+
112+
for (const incrementalDataRecord of this._newIncrementalDataRecords) {
113+
const result = incrementalDataRecord.result;
114+
if (isPromise(result)) {
115+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
116+
result.then((resolved) => this._enqueue(resolved));
117+
} else {
118+
this._enqueue(result);
119+
}
120+
}
121+
this._newIncrementalDataRecords.clear();
122+
139123
return newPending;
140124
}
141125

@@ -210,9 +194,6 @@ export class IncrementalGraph {
210194
this._removePending(deferredFragmentNode);
211195
for (const child of deferredFragmentNode.children) {
212196
this._newPending.add(child);
213-
for (const result of child.results) {
214-
this._enqueue(result);
215-
}
216197
}
217198
return reconcilableResults;
218199
}
@@ -251,6 +232,30 @@ export class IncrementalGraph {
251232
}
252233
}
253234

235+
private _addDeferredGroupedFieldSetRecord(
236+
deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord,
237+
): void {
238+
for (const deferredFragmentRecord of deferredGroupedFieldSetRecord.deferredFragmentRecords) {
239+
const deferredFragmentNode = this._addDeferredFragmentNode(
240+
deferredFragmentRecord,
241+
);
242+
if (this._pending.has(deferredFragmentNode)) {
243+
this._newIncrementalDataRecords.add(deferredGroupedFieldSetRecord);
244+
}
245+
deferredFragmentNode.deferredGroupedFieldSetRecords.add(
246+
deferredGroupedFieldSetRecord,
247+
);
248+
}
249+
}
250+
251+
private _addStreamItemsRecord(streamItemsRecord: StreamItemsRecord): void {
252+
const streamRecord = streamItemsRecord.streamRecord;
253+
if (!this._pending.has(streamRecord)) {
254+
this._newPending.add(streamRecord);
255+
}
256+
this._newIncrementalDataRecords.add(streamItemsRecord);
257+
}
258+
254259
private _addDeferredFragmentNode(
255260
deferredFragmentRecord: DeferredFragmentRecord,
256261
): DeferredFragmentNode {
@@ -263,7 +268,6 @@ export class IncrementalGraph {
263268
deferredFragmentNode = {
264269
deferredFragmentRecord,
265270
deferredGroupedFieldSetRecords: new Set(),
266-
results: [],
267271
reconcilableResults: new Set(),
268272
children: [],
269273
};
@@ -281,30 +285,6 @@ export class IncrementalGraph {
281285
return deferredFragmentNode;
282286
}
283287

284-
private _enqueueCompletedDeferredGroupedFieldSet(
285-
result: DeferredGroupedFieldSetResult,
286-
): void {
287-
let isPending = false;
288-
for (const deferredFragmentRecord of result.deferredGroupedFieldSetRecord
289-
.deferredFragmentRecords) {
290-
const deferredFragmentNode = this._deferredFragmentNodes.get(
291-
deferredFragmentRecord,
292-
);
293-
// TODO: add test case?
294-
/* c8 ignore next 3 */
295-
if (deferredFragmentNode === undefined) {
296-
continue;
297-
}
298-
if (this._pending.has(deferredFragmentNode)) {
299-
isPending = true;
300-
}
301-
deferredFragmentNode.results.push(result);
302-
}
303-
if (isPending) {
304-
this._enqueue(result);
305-
}
306-
}
307-
308288
private *_yieldCurrentCompletedIncrementalData(
309289
first: IncrementalDataRecordResult,
310290
): Generator<IncrementalDataRecordResult> {

src/execution/__tests__/defer-test.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,20 @@ describe('Execute: defer directive', () => {
367367
},
368368
id: '0',
369369
},
370+
],
371+
completed: [{ id: '0' }],
372+
hasNext: true,
373+
},
374+
{
375+
incremental: [
370376
{
371377
data: {
372378
friends: [{ name: 'Han' }, { name: 'Leia' }, { name: 'C-3PO' }],
373379
},
374380
id: '1',
375381
},
376382
],
377-
completed: [{ id: '0' }, { id: '1' }],
383+
completed: [{ id: '1' }],
378384
hasNext: false,
379385
},
380386
]);
@@ -977,27 +983,37 @@ describe('Execute: defer directive', () => {
977983
hasNext: true,
978984
},
979985
{
980-
pending: [
981-
{ id: '1', path: ['hero', 'nestedObject'] },
982-
{ id: '2', path: ['hero', 'nestedObject', 'deeperObject'] },
983-
],
986+
pending: [{ id: '1', path: ['hero', 'nestedObject'] }],
984987
incremental: [
985988
{
986989
data: { bar: 'bar' },
987990
id: '0',
988991
subPath: ['nestedObject', 'deeperObject'],
989992
},
993+
],
994+
completed: [{ id: '0' }],
995+
hasNext: true,
996+
},
997+
{
998+
pending: [{ id: '2', path: ['hero', 'nestedObject', 'deeperObject'] }],
999+
incremental: [
9901000
{
9911001
data: { baz: 'baz' },
9921002
id: '1',
9931003
subPath: ['deeperObject'],
9941004
},
1005+
],
1006+
completed: [{ id: '1' }],
1007+
hasNext: true,
1008+
},
1009+
{
1010+
incremental: [
9951011
{
9961012
data: { bak: 'bak' },
9971013
id: '2',
9981014
},
9991015
],
1000-
completed: [{ id: '0' }, { id: '1' }, { id: '2' }],
1016+
completed: [{ id: '2' }],
10011017
hasNext: false,
10021018
},
10031019
]);

src/execution/__tests__/stream-test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,10 @@ describe('Execute: stream directive', () => {
14441444
},
14451445
{
14461446
incremental: [
1447+
{
1448+
items: [{ name: 'Luke' }],
1449+
id: '1',
1450+
},
14471451
{
14481452
data: { scalarField: null },
14491453
id: '0',
@@ -1455,10 +1459,6 @@ describe('Execute: stream directive', () => {
14551459
},
14561460
],
14571461
},
1458-
{
1459-
items: [{ name: 'Luke' }],
1460-
id: '1',
1461-
},
14621462
],
14631463
completed: [{ id: '0' }],
14641464
hasNext: true,
@@ -1946,14 +1946,14 @@ describe('Execute: stream directive', () => {
19461946
value: {
19471947
pending: [{ id: '2', path: ['friendList', 1], label: 'DeferName' }],
19481948
incremental: [
1949-
{
1950-
data: { name: 'Luke' },
1951-
id: '0',
1952-
},
19531949
{
19541950
items: [{ id: '2' }],
19551951
id: '1',
19561952
},
1953+
{
1954+
data: { name: 'Luke' },
1955+
id: '0',
1956+
},
19571957
],
19581958
completed: [{ id: '0' }],
19591959
hasNext: true,
@@ -2047,14 +2047,14 @@ describe('Execute: stream directive', () => {
20472047
value: {
20482048
pending: [{ id: '2', path: ['friendList', 1], label: 'DeferName' }],
20492049
incremental: [
2050-
{
2051-
data: { name: 'Luke' },
2052-
id: '0',
2053-
},
20542050
{
20552051
items: [{ id: '2' }],
20562052
id: '1',
20572053
},
2054+
{
2055+
data: { name: 'Luke' },
2056+
id: '0',
2057+
},
20582058
],
20592059
completed: [{ id: '0' }],
20602060
hasNext: true,

0 commit comments

Comments
 (0)