haeganm opened a new pull request, #72770:
URL: https://github.com/apache/airflow/pull/72770

   `AppflowHook.run_flow` ends by calling `_log_execution_description`, which 
looked up the execution it just ran in a single unpaginated 
`DescribeFlowExecutionRecords` call:
   
   ```python
   response_desc = self.conn.describe_flow_execution_records(flowName=flow_name)
   last_execs = {fe["executionId"]: fe for fe in 
response_desc["flowExecutions"]}
   exec_details = last_execs[execution_id]
   ```
   
   `maxResults` defaults to 20 and the response carries a `nextToken`, and the 
API does not document any ordering, so the execution is not guaranteed to be on 
that first page. When it is not, that dict lookup raises `KeyError` and the 
task fails even though AppFlow reported the flow as complete. 
`wait_for_completion` defaults to `True`, so every AppFlow operator goes 
through this.
   
   `AppflowRecordsShortCircuitOperator._has_new_records_func` already treats 
the same API as paginated, so this brings the hook in line with it.
   
   ### What changed
   
   * `_log_execution_description` walks pages until it finds the execution, 
asking for 100 records per page, which is the API maximum. In practice that is 
one call.
   * If no record is found on any page it logs a warning instead of raising. 
This is a behavior change and it is deliberate: the helper only exists to log 
the execution details, so it should not be able to fail a run that AppFlow 
already reported as successful.
   * The waiter in `run_flow` reads the same API, so it now asks for 100 
records per page as well. Botocore waiters cannot paginate, so this widens the 
window rather than closing it. Called out below.
   * `MAX_EXECUTION_RECORDS_PER_PAGE = 100` so both call sites use one value.
   
   ### Tests
   
   `test_run_flow` asserted the old call signature, so it now expects 
`maxResults`. Two tests added: one where the execution is on the second page, 
one where no record comes back at all.
   
   With the source change reverted and the new tests kept, both new behaviors 
fail on the bug itself:
   
   ```
   FAILED test_execution_record_on_a_later_page - KeyError: 'ex_id'
   FAILED test_no_matching_execution_record - KeyError: 'ex_id'
   2 failed in 10.44s
   ```
   
   at `hooks/appflow.py:86`, which is the `last_execs[execution_id]` lookup. 
With the fix in place:
   
   ```
   tests/unit/amazon/aws/hooks/test_appflow.py .....       5 passed in 8.37s
   ```
   
   `tests/unit/amazon/aws/operators/test_appflow.py` gives 6 passed and 7 
errors both before and after this change. Those 7 are `db_test` cases that need 
fixtures my local harness does not provide, so they are unrun rather than 
passing, and they are unaffected either way. CI will cover them.
   
   `ruff==0.16.4` (the pinned version) on both changed files: `All checks 
passed!` and `2 files already formatted`.
   
   Reproduced and tested against `apache-airflow==3.3.1`, 
`apache-airflow-providers-amazon==9.35.1`, `botocore==1.43.90`, Python 3.12.14 
on Linux.
   
   ### Not fixed here
   
   The waiter acceptors filter 
`flowExecutions[?executionId=='{{EXECUTION_ID}}']` out of the same call, so 
with a lot of execution records the waiter can still miss the execution and 
poll until `max_attempts` is exhausted on a flow that actually finished. Fixing 
that properly means not using a botocore waiter for this, which felt like a 
separate change. Happy to take it on if you would like it in the same PR.
   
   closes: #72769
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Claude following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to