@@ -105,11 +105,32 @@ public DataflowMapTaskExecutor create(
105105 Networks .replaceDirectedNetworkNodes (
106106 network , createOutputReceiversTransform (stageName , counterSet ));
107107
108- // Swap out all the ParallelInstruction nodes with Operation nodes
109- Networks .replaceDirectedNetworkNodes (
110- network ,
111- createOperationTransformForParallelInstructionNodes (
112- stageName , network , options , readerFactory , sinkFactory , executionContext ));
108+ // Swap out all the ParallelInstruction nodes with Operation nodes. While updating the network,
109+ // we keep track of
110+ // the created Operations so that if an exception is encountered we can properly abort started
111+ // operations.
112+ ArrayList <Operation > createdOperations = new ArrayList <>();
113+ try {
114+ Networks .replaceDirectedNetworkNodes (
115+ network ,
116+ createOperationTransformForParallelInstructionNodes (
117+ stageName ,
118+ network ,
119+ options ,
120+ readerFactory ,
121+ sinkFactory ,
122+ executionContext ,
123+ createdOperations ));
124+ } catch (RuntimeException exn ) {
125+ for (Operation o : createdOperations ) {
126+ try {
127+ o .abort ();
128+ } catch (Exception exn2 ) {
129+ exn .addSuppressed (exn2 );
130+ }
131+ }
132+ throw exn ;
133+ }
113134
114135 // Collect all the operations within the network and attach all the operations as receivers
115136 // to preceding output receivers.
@@ -144,7 +165,8 @@ Function<Node, Node> createOperationTransformForParallelInstructionNodes(
144165 final PipelineOptions options ,
145166 final ReaderFactory readerFactory ,
146167 final SinkFactory sinkFactory ,
147- final DataflowExecutionContext <?> executionContext ) {
168+ final DataflowExecutionContext <?> executionContext ,
169+ final List <Operation > createdOperations ) {
148170
149171 return new TypeSafeNodeFunction <ParallelInstructionNode >(ParallelInstructionNode .class ) {
150172 @ Override
@@ -156,27 +178,31 @@ public Node typedApply(ParallelInstructionNode node) {
156178 instruction .getOriginalName (),
157179 instruction .getSystemName (),
158180 instruction .getName ());
181+ OperationNode result ;
159182 try {
160183 DataflowOperationContext context = executionContext .createOperationContext (nameContext );
161184 if (instruction .getRead () != null ) {
162- return createReadOperation (
163- network , node , options , readerFactory , executionContext , context );
185+ result =
186+ createReadOperation (
187+ network , node , options , readerFactory , executionContext , context );
164188 } else if (instruction .getWrite () != null ) {
165- return createWriteOperation (node , options , sinkFactory , executionContext , context );
189+ result = createWriteOperation (node , options , sinkFactory , executionContext , context );
166190 } else if (instruction .getParDo () != null ) {
167- return createParDoOperation (network , node , options , executionContext , context );
191+ result = createParDoOperation (network , node , options , executionContext , context );
168192 } else if (instruction .getPartialGroupByKey () != null ) {
169- return createPartialGroupByKeyOperation (
170- network , node , options , executionContext , context );
193+ result =
194+ createPartialGroupByKeyOperation ( network , node , options , executionContext , context );
171195 } else if (instruction .getFlatten () != null ) {
172- return createFlattenOperation (network , node , context );
196+ result = createFlattenOperation (network , node , context );
173197 } else {
174198 throw new IllegalArgumentException (
175199 String .format ("Unexpected instruction: %s" , instruction ));
176200 }
177201 } catch (Exception e ) {
178202 throw new RuntimeException (e );
179203 }
204+ createdOperations .add (result .getOperation ());
205+ return result ;
180206 }
181207 };
182208 }
@@ -328,7 +354,6 @@ public Node typedApply(InstructionOutputNode input) {
328354 Coder <?> coder =
329355 CloudObjects .coderFromCloudObject (CloudObject .fromSpec (cloudOutput .getCodec ()));
330356
331- @ SuppressWarnings ("unchecked" )
332357 ElementCounter outputCounter =
333358 new DataflowOutputCounter (
334359 cloudOutput .getName (),
0 commit comments