rebenitez1802 commented on code in PR #45845:
URL: https://github.com/apache/superset/pull/45845#discussion_r4448356573


##########
superset/db_engine_specs/impala.py:
##########
@@ -130,56 +143,289 @@ def execute(
     ) -> None:
         try:
             cursor.execute_async(query)
+        except TIME_LIMIT_EXCEPTIONS:
+            raise
         except Exception as ex:
             raise cls.get_dbapi_mapped_exception(ex) from ex
 
     @classmethod
+    @guard_cursor
     def fetch_data(cls, cursor: Any, limit: int | None = None) -> 
list[tuple[Any, ...]]:
         """Wait for asynchronous operations using the public cursor API."""
-        if callable(getattr(cursor, "execute_async", None)):
-            from impala.error import Error
+        try:
+            if callable(getattr(cursor, "execute_async", None)):
+                from impala.error import Error
+
+                deadline = time.monotonic() + app.config["SQLLAB_TIMEOUT"]
+                try:
+                    while cursor.is_executing():
+                        if time.monotonic() >= deadline:
+                            cls._cancel_operation(cursor)
+                            raise TimeoutError(
+                                "Timed out waiting for the Impala operation"
+                            )
+                        time.sleep(0.1)
+                    if cursor.execution_failed():
+                        # Fetching surfaces the driver's detailed asynchronous 
error,
+                        # including errors on statements that produce no 
result set.
+                        cursor.fetchall()
+                except Error as ex:
+                    raise cls.get_dbapi_mapped_exception(ex) from ex
+            return super().fetch_data(cursor, limit)
+        except TIME_LIMIT_EXCEPTIONS:
+            cls._cancel_operation_on_time_limit(cursor)
+            raise

Review Comment:
   🟡 Medium (non-blocking): this cancel now runs inside the short time-limit 
gap of `get_df` callers such as alerts
   
   This handler sends cancel, close-operation and close-session before the 
limit propagates. On master, `fetch_data` sent nothing here, and the query 
leaked instead. SQL Lab has 60 s between the Celery soft and hard limits. 
Alerts and reports have only `ALERT_REPORTS_WORKING_TIME_OUT_LAG - 
ALERT_REPORTS_WORKING_SOFT_TIME_OUT_LAG` = 9 s by default.
   
   On Impala 4.5.2 a cancel can block for up to `FETCH_ROWS_TIMEOUT_MS` (about 
10 s) while a fetch is in flight. With a fake server whose 
`CloseImpalaOperation` takes 12 s, `fetch_data` returned after 13.0 s here and 
1.0 s on master. Past 9 s the alert task is hard-killed before it records 
ERROR, and its execution log stays "working".
   
   There's no small fix that keeps the cancel, so this is your call. Options:
   - **Cancel only, then abandon.** In this handler only, send just 
`cancel_operation(reset_state=False)` and then abandon the cursor locally, 
keeping the full close in `handle_cursor`. This shortens the cleanup but 
doesn't bound the cancel itself.
   - **Document the trade-off.** Recommend a driver network timeout, or a 
larger alert lag, for deployments that run alerts on Impala.



##########
tests/unit_tests/db_engine_specs/test_impala_transport.py:
##########
@@ -0,0 +1,916 @@
+# 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.
+"""
+Time-limit cancellation over real impyla Thrift transports.
+
+A local HiveServer2 stand-in serves impyla's binary, SASL PLAIN and HTTP
+transports. The time limit is raised right after a reply header is read, as a
+signal landing at that point would, so the rest of the reply is left in the
+client's buffers.
+"""
+
+from __future__ import annotations
+
+import signal
+import socket
+import struct
+import threading
+from collections.abc import Iterator
+from contextlib import closing
+from dataclasses import dataclass, field
+from typing import Any
+from unittest.mock import Mock, patch
+
+import pytest
+from celery.exceptions import SoftTimeLimitExceeded
+
+from superset.constants import QUERY_EARLY_CANCEL_KEY
+from superset.db_engine_specs.impala import ImpalaEngineSpec as spec  # noqa: 
N813
+from superset.errors import ErrorLevel, SupersetErrorType
+from superset.exceptions import SupersetTimeoutException
+from superset.sql.execution.executor import _LimitedCursor
+
+hs2 = pytest.importorskip("impala.hiveserver2")
+ttypes = pytest.importorskip("impala._thrift_gen.TCLIService.ttypes")
+TCLIService = pytest.importorskip("impala._thrift_gen.TCLIService.TCLIService")

Review Comment:
   🟡 Medium (non-blocking): CI never runs these transport tests
   
   The unit-test job installs `requirements/development.txt`, which has 
`pyhive==0.7.0` but not impyla, thrift or thrift_sasl. So these `importorskip` 
calls, and the matching ones in `test_hive_transport.py`, skip both files in 
CI. That's about 1,200 lines, including the 30 new clean-transport regression 
cases. They only run locally: with the drivers installed, both files pass (466 
tests together with the mock suites).
   
   Fix: add `hive` and `impala` to the extras list in 
`requirements/development.in` (`-e .[development,bigquery,...]`), then 
recompile `requirements/development.txt`. Or install those extras in the 
unit-test workflow. Note that the `hive` extra pins `thrift>=0.25.0`, so the 
suites should be re-checked on that version.



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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to