@@ -48,6 +48,19 @@ interface SubsequentIncrementalExecutionResultContext<TData = any> {
4848 completed : Array < CompletedResult > ;
4949}
5050
51+ /**
52+ * The IncrementalPublisherState Enum tracks the state of the IncrementalPublisher, which is initialized to
53+ * "Started". When there are no more incremental results to publish, the state is set to "Completed". On the
54+ * next call to next, clean-up is potentially performed and the state is set to "Finished".
55+ *
56+ * If the IncrementalPublisher is ended early, it may be advanced directly from "Started" to "Finished".
57+ */
58+ enum IncrementalPublisherState {
59+ Started = 1 ,
60+ Completed = 2 ,
61+ Finished = 3 ,
62+ }
63+
5164/**
5265 * This class is used to publish incremental results to the client, enabling semi-concurrent
5366 * execution while preserving result order.
@@ -113,18 +126,32 @@ class IncrementalPublisher {
113126 void ,
114127 void
115128 > {
116- let isDone = false ;
129+ let incrementalPublisherState : IncrementalPublisherState = IncrementalPublisherState . Started ;
130+
131+ const _finish = async ( ) : Promise < void > => {
132+ incrementalPublisherState = IncrementalPublisherState . Finished ;
133+ this . _incrementalGraph . abort ( ) ;
134+ await this . _returnAsyncIterators ( ) ;
135+ } ;
117136
118137 this . _context . signal ?. addEventListener ( 'abort' , ( ) => {
119- this . _incrementalGraph . completedIncrementalData ( ) . return ( ) ;
138+ this . _incrementalGraph . abort ( ) ;
120139 } ) ;
121140
122141 const _next = async ( ) : Promise <
123142 IteratorResult < SubsequentIncrementalExecutionResult < TData > , void >
124143 > => {
125- if ( isDone ) {
126- await this . _returnAsyncIteratorsIgnoringErrors ( ) ;
127- return { value : undefined , done : true } ;
144+ switch ( incrementalPublisherState ) {
145+ case IncrementalPublisherState . Finished : {
146+ return { value : undefined , done : true } ;
147+ }
148+ case IncrementalPublisherState . Completed : {
149+ await _finish ( ) ;
150+ return { value : undefined , done : true } ;
151+ }
152+ case IncrementalPublisherState . Started : {
153+ // continue
154+ }
128155 }
129156
130157 const context : SubsequentIncrementalExecutionResultContext < TData > = {
@@ -133,12 +160,10 @@ class IncrementalPublisher {
133160 completed : [ ] ,
134161 } ;
135162
136- let currentCompletedIncrementalData =
137- this . _incrementalGraph . currentCompletedIncrementalData ( ) ;
138- const completedIncrementalData = this . _incrementalGraph . completedIncrementalData ( ) ;
139- const asyncIterator = completedIncrementalData [ Symbol . asyncIterator ] ( ) ;
163+ let batch : Iterable < IncrementalDataRecordResult > | undefined =
164+ this . _incrementalGraph . currentCompletedBatch ( ) ;
140165 do {
141- for ( const completedResult of currentCompletedIncrementalData ) {
166+ for ( const completedResult of batch ) {
142167 this . _handleCompletedIncrementalData ( completedResult , context ) ;
143168 }
144169
@@ -147,7 +172,7 @@ class IncrementalPublisher {
147172 const hasNext = this . _incrementalGraph . hasNext ( ) ;
148173
149174 if ( ! hasNext ) {
150- isDone = true ;
175+ incrementalPublisherState = IncrementalPublisherState . Completed ;
151176 }
152177
153178 const subsequentIncrementalExecutionResult : SubsequentIncrementalExecutionResult < TData > =
@@ -169,31 +194,27 @@ class IncrementalPublisher {
169194 return { value : subsequentIncrementalExecutionResult , done : false } ;
170195 }
171196
172- const iteration = await asyncIterator . next ( ) ;
173- currentCompletedIncrementalData = iteration . value ;
174- } while ( currentCompletedIncrementalData !== undefined ) ;
197+ batch = await this . _incrementalGraph . nextCompletedBatch ( ) ;
198+ } while ( batch !== undefined ) ;
175199
176200 if ( this . _context . signal ?. aborted ) {
177201 throw this . _context . signal . reason ;
178202 }
179203
180- await this . _returnAsyncIteratorsIgnoringErrors ( ) ;
181204 return { value : undefined , done : true } ;
182205 } ;
183206
184207 const _return = async ( ) : Promise <
185208 IteratorResult < SubsequentIncrementalExecutionResult < TData > , void >
186209 > => {
187- isDone = true ;
188- await this . _returnAsyncIterators ( ) ;
210+ await _finish ( ) ;
189211 return { value : undefined , done : true } ;
190212 } ;
191213
192214 const _throw = async (
193215 error ?: unknown ,
194216 ) : Promise < IteratorResult < SubsequentIncrementalExecutionResult < TData > , void > > => {
195- isDone = true ;
196- await this . _returnAsyncIterators ( ) ;
217+ await _finish ( ) ;
197218 return Promise . reject ( error ) ;
198219 } ;
199220
@@ -400,7 +421,7 @@ class IncrementalPublisher {
400421 }
401422
402423 private async _returnAsyncIterators ( ) : Promise < void > {
403- await this . _incrementalGraph . completedIncrementalData ( ) . return ( ) ;
424+ await this . _incrementalGraph . abort ( ) ;
404425
405426 const cancellableStreams = this . _context . cancellableStreams ;
406427 if ( cancellableStreams === undefined ) {
@@ -414,10 +435,4 @@ class IncrementalPublisher {
414435 }
415436 await Promise . all ( promises ) ;
416437 }
417-
418- private async _returnAsyncIteratorsIgnoringErrors ( ) : Promise < void > {
419- await this . _returnAsyncIterators ( ) . catch ( ( ) => {
420- // Ignore errors
421- } ) ;
422- }
423438}
0 commit comments