vandonr-amz commented on code in PR #30463:
URL: https://github.com/apache/airflow/pull/30463#discussion_r1228768476


##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(
+    waiter,
+    waiter_delay,
+    max_attempts,
+    state_args,
+    failure_message,
+    status_message,
+):
+    log = logging.getLogger(__name__)
+    attempt = 0
+    while attempt < max_attempts:
+        attempt += 1
+        try:
+            waiter.wait(
+                **state_args,
+                WaiterConfig={
+                    "Delay": 1,
+                    "MaxAttempts": 1,
+                },
+            )
+            break
+        except WaiterError as error:
+            if "terminal failure" in str(error):
+                raise AirflowException(f"{failure_message}: {error}")
+            response_data = []
+            for arg in status_message["args"]:
+                response_data.append(get_state(error.last_response, arg))
+
+            log.info(status_message["message"] + " : " + " - 
".join(response_data))
+            time.sleep(waiter_delay)
+    if attempt >= max_attempts:

Review Comment:
   you're writing the same check twice, wdyt about a `while True` and putting 
this inside the loop ?



##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(
+    waiter,
+    waiter_delay,
+    max_attempts,
+    state_args,
+    failure_message,
+    status_message,
+):
+    log = logging.getLogger(__name__)
+    attempt = 0
+    while attempt < max_attempts:
+        attempt += 1
+        try:
+            waiter.wait(
+                **state_args,
+                WaiterConfig={
+                    "Delay": 1,

Review Comment:
   Can we omit this parameter ? If not, maybe add a comment explaining that 
it's not meaningful here.



##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(
+    waiter,
+    waiter_delay,
+    max_attempts,
+    state_args,
+    failure_message,
+    status_message,
+):
+    log = logging.getLogger(__name__)
+    attempt = 0
+    while attempt < max_attempts:
+        attempt += 1
+        try:
+            waiter.wait(
+                **state_args,
+                WaiterConfig={
+                    "Delay": 1,
+                    "MaxAttempts": 1,
+                },
+            )
+            break
+        except WaiterError as error:
+            if "terminal failure" in str(error):
+                raise AirflowException(f"{failure_message}: {error}")
+            response_data = []
+            for arg in status_message["args"]:
+                response_data.append(get_state(error.last_response, arg))
+
+            log.info(status_message["message"] + " : " + " - 
".join(response_data))

Review Comment:
   you shouldn't concatenate strings for logs, use `%s` formatting instead, so 
that if users disable info logs, they don't pay the cost of string manipulation.
   (you could even do away without the `join`, at the expense of readability, 
I'll let you judge)



##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(

Review Comment:
   I disagree with you, and I don't think the question is whether it's 
_possible_ to do this with tenacity, but rather if using tenacity improves 
readability and maintainability.
   If I have to read through pages of tenacity documentation to understand 
what's going on, it's not really a win even if it reduces the number of lines 
of code.
   
   Tenacity is intended to retry things like network errors & such, using it 
here as an alternative `while` loop would break the [principle of least 
surprise](https://en.wikipedia.org/wiki/Principle_of_least_astonishment) for 
readers of this code.



##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(
+    waiter,
+    waiter_delay,
+    max_attempts,
+    state_args,
+    failure_message,
+    status_message,

Review Comment:
   would be nice to have type annotations here



##########
airflow/providers/amazon/aws/utils/waiter_with_logging.py:
##########
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+import time
+
+from botocore.exceptions import WaiterError
+
+from airflow.exceptions import AirflowException
+
+
+def wait(
+    waiter,
+    waiter_delay,
+    max_attempts,
+    state_args,
+    failure_message,
+    status_message,
+):
+    log = logging.getLogger(__name__)
+    attempt = 0
+    while attempt < max_attempts:
+        attempt += 1
+        try:
+            waiter.wait(
+                **state_args,
+                WaiterConfig={
+                    "Delay": 1,
+                    "MaxAttempts": 1,
+                },
+            )
+            break
+        except WaiterError as error:
+            if "terminal failure" in str(error):
+                raise AirflowException(f"{failure_message}: {error}")
+            response_data = []
+            for arg in status_message["args"]:
+                response_data.append(get_state(error.last_response, arg))
+
+            log.info(status_message["message"] + " : " + " - 
".join(response_data))
+            time.sleep(waiter_delay)
+    if attempt >= max_attempts:
+        raise AirflowException("Waiter error: max attempts reached")
+
+
+def get_state(response, keys) -> str:

Review Comment:
   We could use a JMESPath expression here, just like we define them in waiters.
   This function has relatively complicated logic, and no test, using an 
external package would make all this vanish ;)



-- 
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