|
40 | 40 | from apache_beam.options.pipeline_options import SetupOptions |
41 | 41 | from apache_beam.options.pipeline_options import StandardOptions |
42 | 42 | from apache_beam.runners.runner import PipelineResult |
| 43 | +from apache_beam.runners.runner import PipelineState |
43 | 44 | from transformers import DistilBertConfig |
44 | 45 | from transformers import DistilBertForSequenceClassification |
45 | 46 | from transformers import DistilBertTokenizerFast |
@@ -218,6 +219,37 @@ def run_load_pipeline(known_args, pipeline_args): |
218 | 219 | return pipeline.run() |
219 | 220 |
|
220 | 221 |
|
| 222 | +def _wait_until_dataflow_terminal( |
| 223 | + result: PipelineResult, |
| 224 | + *, |
| 225 | + phase: str, |
| 226 | + max_wait_secs: float = 3600.0, |
| 227 | + poll_secs: float = 5.0) -> None: |
| 228 | + """Poll until the Dataflow job is terminal. |
| 229 | +
|
| 230 | + ``DataflowPipelineResult.wait_until_finish`` can return while the job is still |
| 231 | + in ``CANCELLING`` (internal poll uses a short countdown). Avoid |
| 232 | + ``wait_until_finish(duration=None)`` after cancel; poll ``state`` so each |
| 233 | + iteration refreshes job status from the API. |
| 234 | + """ |
| 235 | + deadline = time.time() + max_wait_secs |
| 236 | + while time.time() < deadline: |
| 237 | + if PipelineState.is_terminal(result.state): |
| 238 | + logging.info( |
| 239 | + '%s: job %s finished in terminal state %s', |
| 240 | + phase, |
| 241 | + result.job_id(), |
| 242 | + result.state) |
| 243 | + return |
| 244 | + time.sleep(poll_secs) |
| 245 | + logging.warning( |
| 246 | + '%s: job %s not terminal after %.0f s (last state %s); continuing.', |
| 247 | + phase, |
| 248 | + result.job_id(), |
| 249 | + max_wait_secs, |
| 250 | + result.state) |
| 251 | + |
| 252 | + |
221 | 253 | def run( |
222 | 254 | argv=None, save_main_session=True, test_pipeline=None) -> PipelineResult: |
223 | 255 | known_args, pipeline_args = parse_known_args(argv) |
@@ -286,7 +318,7 @@ def run( |
286 | 318 | result.cancel() |
287 | 319 | # Wait until the job is fully cancelled before tearing down Pub/Sub; |
288 | 320 | # otherwise Dataflow can still be using the subscription (NOT_FOUND). |
289 | | - result.wait_until_finish(duration=None) |
| 321 | + _wait_until_dataflow_terminal(result, phase='after cancel') |
290 | 322 |
|
291 | 323 | cleanup_pubsub_resources( |
292 | 324 | project=known_args.project, |
|
0 commit comments