1818package org .apache .beam .sdk .fn .data ;
1919
2020import static org .apache .beam .vendor .guava .v32_1_2_jre .com .google .common .base .Preconditions .checkNotNull ;
21+ import static org .apache .beam .vendor .guava .v32_1_2_jre .com .google .common .base .Preconditions .checkState ;
2122
2223import java .io .IOException ;
2324import java .util .Collections ;
@@ -98,15 +99,31 @@ public void prepareForInstruction(
9899 String instructionId , StreamObserver <Elements > outboundObserver ) {
99100 if (timeLimit > 0 ) {
100101 synchronized (flushLock ) {
102+ checkState (this .instructionId == null && this .outboundObserver == null );
101103 this .instructionId = instructionId ;
102104 this .outboundObserver = outboundObserver ;
103105 }
104106 } else {
107+ checkState (this .instructionId == null && this .outboundObserver == null );
105108 this .instructionId = instructionId ;
106109 this .outboundObserver = outboundObserver ;
107110 }
108111 }
109112
113+ public void finishInstruction () {
114+ if (timeLimit > 0 ) {
115+ synchronized (flushLock ) {
116+ checkState (this .instructionId != null && this .outboundObserver != null );
117+ this .instructionId = null ;
118+ this .outboundObserver = null ;
119+ }
120+ } else {
121+ checkState (this .instructionId != null && this .outboundObserver != null );
122+ this .instructionId = null ;
123+ this .outboundObserver = null ;
124+ }
125+ }
126+
110127 /** Starts the flushing daemon thread if data_buffer_time_limit_ms is set. */
111128 public void start () {
112129 if (timeLimit > 0 && this .flushFuture == null ) {
@@ -198,7 +215,6 @@ public Elements sendOrCollectBufferedDataAndFinishOutboundStreams() {
198215 } else {
199216 bufferedElements = convertBufferForTransmission ();
200217 }
201- checkNotNull (instructionId );
202218 LOG .debug (
203219 "Closing streams for instruction {} and outbound data {} and timers {}." ,
204220 instructionId ,
@@ -224,13 +240,10 @@ public Elements sendOrCollectBufferedDataAndFinishOutboundStreams() {
224240 entry .getValue ().resetStats ();
225241 }
226242 // This is the end of the bundle so we reset state to prepare for future bundles.
227- instructionId = null ;
228243 if (collectElementsIfNoFlushes && !hasFlushedForBundle ) {
229- outboundObserver = null ;
230244 return bufferedElements .build ();
231245 }
232246 checkNotNull (outboundObserver ).onNext (bufferedElements .build ());
233- outboundObserver = null ;
234247 hasFlushedForBundle = false ;
235248 return null ;
236249 }
@@ -247,7 +260,6 @@ public void discard() {
247260 }
248261
249262 private Elements .Builder convertBufferForTransmission () {
250- checkNotNull (instructionId );
251263 Elements .Builder bufferedElements = Elements .newBuilder ();
252264 for (Map .Entry <String , Receiver <?>> entry : outputDataReceivers .entrySet ()) {
253265 if (!entry .getValue ().hasBufferedOutput ()) {
0 commit comments