Skip to content

Commit 268ac37

Browse files
committed
consolidate payloads
1 parent 1a4d602 commit 268ac37

File tree

3 files changed

+91
-167
lines changed

3 files changed

+91
-167
lines changed

src/execution/IncrementalPublisher.ts

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ export interface FormattedCompletedResult {
162162
errors?: ReadonlyArray<GraphQLError>;
163163
}
164164

165+
interface IncrementalAggregate {
166+
newPendingSources: Set<DeferredFragmentRecord | StreamRecord>;
167+
incrementalResults: Array<IncrementalResult>;
168+
completedResults: Array<CompletedResult>;
169+
}
170+
165171
/**
166172
* This class is used to publish incremental results to the client, enabling semi-concurrent
167173
* execution while preserving result order.
@@ -399,20 +405,28 @@ export class IncrementalPublisher {
399405
return { value: undefined, done: true };
400406
}
401407

402-
for (const item of this._released) {
403-
this._pending.delete(item);
404-
}
405-
const released = this._released;
406-
this._released = new Set();
408+
if (this._released.size > 0) {
409+
let aggregate = this._incrementalInitializer();
410+
do {
411+
for (const item of this._released) {
412+
this._pending.delete(item);
413+
}
414+
const released = this._released;
415+
this._released = new Set();
407416

408-
const result = this._getIncrementalResult(released);
417+
aggregate = this._incrementalReducer(aggregate, released);
418+
} while (this._released.size > 0);
409419

410-
if (this._pending.size === 0) {
411-
isDone = true;
412-
}
420+
const hasNext = this._pending.size > 0;
421+
422+
if (!hasNext) {
423+
isDone = true;
424+
}
413425

414-
if (result !== undefined) {
415-
return { value: result, done: false };
426+
return {
427+
value: this._incrementalFinalizer(aggregate),
428+
done: false,
429+
};
416430
}
417431

418432
// eslint-disable-next-line no-await-in-loop
@@ -494,37 +508,20 @@ export class IncrementalPublisher {
494508
this._trigger();
495509
}
496510

497-
private _getIncrementalResult(
498-
completedRecords: ReadonlySet<SubsequentResultRecord>,
499-
): SubsequentIncrementalExecutionResult | undefined {
500-
const { pending, incremental, completed } =
501-
this._processPending(completedRecords);
502-
503-
const hasNext = this._pending.size > 0;
504-
if (incremental.length === 0 && completed.length === 0 && hasNext) {
505-
return undefined;
506-
}
507-
508-
const result: SubsequentIncrementalExecutionResult = { hasNext };
509-
if (pending.length) {
510-
result.pending = pending;
511-
}
512-
if (incremental.length) {
513-
result.incremental = incremental;
514-
}
515-
if (completed.length) {
516-
result.completed = completed;
517-
}
518-
519-
return result;
511+
private _incrementalInitializer(): IncrementalAggregate {
512+
return {
513+
newPendingSources: new Set<DeferredFragmentRecord | StreamRecord>(),
514+
incrementalResults: [],
515+
completedResults: [],
516+
};
520517
}
521518

522-
private _processPending(
519+
private _incrementalReducer(
520+
aggregate: IncrementalAggregate,
523521
completedRecords: ReadonlySet<SubsequentResultRecord>,
524-
): IncrementalUpdate {
525-
const newPendingSources = new Set<DeferredFragmentRecord | StreamRecord>();
526-
const incrementalResults: Array<IncrementalResult> = [];
527-
const completedResults: Array<CompletedResult> = [];
522+
): IncrementalAggregate {
523+
const { newPendingSources, incrementalResults, completedResults } =
524+
aggregate;
528525
for (const subsequentResultRecord of completedRecords) {
529526
for (const child of subsequentResultRecord.children) {
530527
if (child.filtered) {
@@ -585,11 +582,30 @@ export class IncrementalPublisher {
585582
}
586583
}
587584

588-
return {
589-
pending: this.pendingSourcesToResults(newPendingSources),
590-
incremental: incrementalResults,
591-
completed: completedResults,
585+
return aggregate;
586+
}
587+
588+
private _incrementalFinalizer(
589+
aggregate: IncrementalAggregate,
590+
): SubsequentIncrementalExecutionResult {
591+
const { newPendingSources, incrementalResults, completedResults } =
592+
aggregate;
593+
const pendingResults = this.pendingSourcesToResults(newPendingSources);
594+
595+
const result: SubsequentIncrementalExecutionResult = {
596+
hasNext: this._pending.size > 0,
592597
};
598+
if (pendingResults.length) {
599+
result.pending = pendingResults;
600+
}
601+
if (incrementalResults.length) {
602+
result.incremental = incrementalResults;
603+
}
604+
if (completedResults.length) {
605+
result.completed = completedResults;
606+
}
607+
608+
return result;
593609
}
594610

595611
private _completedRecordToResult(

src/execution/__tests__/defer-test.ts

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,35 +1174,25 @@ describe('Execute: defer directive', () => {
11741174
hasNext: true,
11751175
},
11761176
{
1177-
pending: [{ path: ['hero', 'nestedObject'] }],
11781177
incremental: [
11791178
{
11801179
data: { bar: 'bar' },
11811180
path: ['hero', 'nestedObject', 'deeperObject'],
11821181
},
1183-
],
1184-
completed: [{ path: ['hero'] }],
1185-
hasNext: true,
1186-
},
1187-
{
1188-
pending: [{ path: ['hero', 'nestedObject', 'deeperObject'] }],
1189-
incremental: [
11901182
{
11911183
data: { baz: 'baz' },
11921184
path: ['hero', 'nestedObject', 'deeperObject'],
11931185
},
1194-
],
1195-
hasNext: true,
1196-
completed: [{ path: ['hero', 'nestedObject'] }],
1197-
},
1198-
{
1199-
incremental: [
12001186
{
12011187
data: { bak: 'bak' },
12021188
path: ['hero', 'nestedObject', 'deeperObject'],
12031189
},
12041190
],
1205-
completed: [{ path: ['hero', 'nestedObject', 'deeperObject'] }],
1191+
completed: [
1192+
{ path: ['hero'] },
1193+
{ path: ['hero', 'nestedObject'] },
1194+
{ path: ['hero', 'nestedObject', 'deeperObject'] },
1195+
],
12061196
hasNext: false,
12071197
},
12081198
]);
@@ -1249,31 +1239,25 @@ describe('Execute: defer directive', () => {
12491239
hasNext: true,
12501240
},
12511241
{
1252-
pending: [{ path: ['hero', 'nestedObject', 'deeperObject'] }],
12531242
incremental: [
12541243
{
12551244
data: {
12561245
foo: 'foo',
12571246
},
12581247
path: ['hero', 'nestedObject', 'deeperObject'],
12591248
},
1260-
],
1261-
completed: [
1262-
{ path: ['hero'] },
1263-
{ path: ['hero', 'nestedObject', 'deeperObject'] },
1264-
],
1265-
hasNext: true,
1266-
},
1267-
{
1268-
incremental: [
12691249
{
12701250
data: {
12711251
bar: 'bar',
12721252
},
12731253
path: ['hero', 'nestedObject', 'deeperObject'],
12741254
},
12751255
],
1276-
completed: [{ path: ['hero', 'nestedObject', 'deeperObject'] }],
1256+
completed: [
1257+
{ path: ['hero'] },
1258+
{ path: ['hero', 'nestedObject', 'deeperObject'] },
1259+
{ path: ['hero', 'nestedObject', 'deeperObject'] },
1260+
],
12771261
hasNext: false,
12781262
},
12791263
]);
@@ -2069,27 +2053,17 @@ describe('Execute: defer directive', () => {
20692053
hasNext: true,
20702054
},
20712055
{
2072-
pending: [
2073-
{ path: ['hero', 'friends', 0] },
2074-
{ path: ['hero', 'friends', 1] },
2075-
{ path: ['hero', 'friends', 2] },
2076-
],
20772056
incremental: [
20782057
{
20792058
data: { name: 'slow', friends: [{}, {}, {}] },
20802059
path: ['hero'],
20812060
},
2082-
],
2083-
completed: [{ path: ['hero'] }],
2084-
hasNext: true,
2085-
},
2086-
{
2087-
incremental: [
20882061
{ data: { name: 'Han' }, path: ['hero', 'friends', 0] },
20892062
{ data: { name: 'Leia' }, path: ['hero', 'friends', 1] },
20902063
{ data: { name: 'C-3PO' }, path: ['hero', 'friends', 2] },
20912064
],
20922065
completed: [
2066+
{ path: ['hero'] },
20932067
{ path: ['hero', 'friends', 0] },
20942068
{ path: ['hero', 'friends', 1] },
20952069
{ path: ['hero', 'friends', 2] },

0 commit comments

Comments
 (0)