Async Thin: call_timeout returns DPY-4024 before RESET completes
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- python
- Lĩnh vực
- backend-api-design, database
Hướng nghiên cứu
Start by reading BaseAsyncProtocol._process_timeout_helper() and trace how _break_external() and _receive_packet(message) handle DATA and RESET marker packets. Compare that flow with the packet sequence described in the issue and inspect related async protocol tests for timeout recovery. Done means a timed out call completes BREAK/RESET recovery before raising DPY-4024, and a subsequent statement does not fail with DPY-4011.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
- What versions are you using?
- Oracle Database Free 23.5.0.24.7 (local testing); Observed in production against Oracle Database 19c.
- python-oracledb 4.0.2 and 26.0.1, Thin mode. The same timeout-helper code is present on main (
c92c8420). - Python 3.13, asyncio, on macOS arm64 and Linux arm64.
- Production also uses uvloop and SQLAlchemy 2.0 (
oracle+oracledb_async), but the reproduction below uses native python-oracledb only. - Oracle Client: not applicable (Thin mode).
- Is it an error or a hang or a crash?
An error after a timeout, followed by a delayed failure when reusing a connection that still reports healthy.
- What error(s) or behavior you are seeing?
With call_timeout = 500, a statement that completes between approximately 500 and 1000 ms can raise DPY-4024 while connection.is_healthy() returns True. The next statement on that connection waits approximately 1 second and fails with:
DPY-4011: the database or network closed the connection
socket timed out while recovering from previous socket timeout
Representative output from the original reproduction on 26.0.1, Linux arm64:
sleep=0.6: call 1 DPY-4024, is_healthy=True
call 2 DPY-4011 after 1.01s
sleep=0.7: call 1 DPY-4024, is_healthy=True
call 2 DPY-4011 after 1.01s
sleep=0.8: call 1 DPY-4024, is_healthy=True
call 2 DPY-4011 after 1.00s
This is timing-dependent: some runs recover successfully or return ORA-01013 on the next call. The same behavior was reproduced on 4.0.2.
Source inspection and packet traces point to incomplete BREAK/RESET recovery in BaseAsyncProtocol._process_timeout_helper():
self._break_external()
await self._receive_packet(message)
self._break_in_progress = False
errors._raise_err(errors.ERR_CALL_TIMEOUT_EXCEEDED, timeout=timeout)
If the first packet received is the completed statement's DATA response rather than a MARKER, the helper raises DPY-4024 without completing RESET. The trace shows the server's RESET marker arriving without a client RESET response. The next call clears buffered packets and sends a request while the server is still waiting for RESET.
- Does your application call init_oracle_client()?
No. Thin mode.
- Include a runnable Python script that shows the problem.
import asyncio
import os
import platform
import sys
import time
import oracledb
PARAMS = dict(
user=os.environ["ORACLE_USER"],
password=os.environ["ORACLE_PASSWORD"],
dsn=os.environ["ORACLE_DSN"],
)
async def main():
for sleep_s in (0.55, 0.6, 0.7, 0.8, 0.9):
async with oracledb.connect_async(**PARAMS) as conn:
print("connection.version:", conn.version)
conn.call_timeout = 500
with conn.cursor() as cur:
try:
await cur.execute(
"begin dbms_session.sleep(:s); end;", [sleep_s]
)
except oracledb.DatabaseError as exc:
print(
f" sleep={sleep_s}: call 1 {exc.args[0].full_code}, "
f"is_healthy={conn.is_healthy()}"
)
start = time.monotonic()
try:
await cur.execute("select 1 from dual")
print(" call 2 ok")
except oracledb.DatabaseError as exc:
print(
f" call 2 {exc.args[0].full_code} "
f"after {time.monotonic() - start:.2f}s"
)
asyncio.run(main())
- Ngôn ngữ chính
- Python
- Star
- 455
- Fork
- 119
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của oracle/python-oracledb
-
bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
oracle/python-oracledb#625 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
oracle/python-oracledb#623 ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
oracle/python-oracledb#622 ·
-
bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 32/100
oracle/python-oracledb#621 · 3 bình luận ·
-
Client Library or Database
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
oracle/python-oracledb#620 · 4 bình luận ·
Tất cả issue của oracle/python-oracledb
Issue tương tự
-
link-rot
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 67/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
developmentseed/titiler-cmr#265 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Insecure Brotli version <1.2.1Có thể đã có người làm @jamescw19 đã nhận hôm nay. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
stac-utils/stac-fastapi-pgstac#438 · 1 reaction ·
-
bug triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày