Async Thin: call_timeout returns DPY-4024 before RESET completes
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 45/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- python
- Ambito
- backend-api-design, database
Direzione di ricerca
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.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
- 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())
- Lingua principale
- Python
- Stelle
- 455
- Fork
- 119
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di oracle/python-oracledb
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
oracle/python-oracledb#625 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
oracle/python-oracledb#623 ·
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
oracle/python-oracledb#622 ·
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 32/100
oracle/python-oracledb#621 · 3 commenti ·
-
Client Library or Database
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
oracle/python-oracledb#620 · 4 commenti ·
Tutte le issue di oracle/python-oracledb
Issue simili
-
README.zh-CN/ja/es still hard-code 501 test counts after README.md went count-freeForse già presa @Aaqibhafeezkhan l’ha presa oggi. Apertabeginner documentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
BistaDinesh03/critique#164 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug IO
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
MrNeRF/LichtFeld-Studio#3824 ·
I maintainer di solito rispondono entro 1 giorno
-
bug confirmed issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
open-webui/open-webui#33200 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Lychee link check failedAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
-
The changelog workflow excludes otelbot but not dependabot, so every Dependabot pull request fails the changelog checkForse già presa @ocelotl l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
open-telemetry/opentelemetry-python#5825 ·
I maintainer di solito rispondono entro 2 giorni