Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async pool.acquire() not working in thick mode #448

Open
migelle74 opened this issue Jan 23, 2025 · 4 comments
Open

async pool.acquire() not working in thick mode #448

migelle74 opened this issue Jan 23, 2025 · 4 comments
Labels
bug Something isn't working patch available

Comments

@migelle74
Copy link

I take example script

import asyncio
import time
import oracledb

CONCURRENCY = 5

sql = """SELECT UNIQUE CURRENT_TIMESTAMP AS CT, sid||'-'||serial# AS SIDSER
         FROM v$session_connect_info
         WHERE sid = SYS_CONTEXT('USERENV', 'SID')"""

async def init_session(connection, requested_tag):
    res = await connection.fetchone(sql)
    print(res[0].strftime("%H:%M:%S.%f"), '- init_session with SID-SERIAL#', res[1])

async def connect_and_query(pool):
    async with pool.acquire() as connection:
        await connection.callproc("dbms_session.sleep", [1])
        res = await connection.fetchone(sql)
        print(res[0].strftime("%H:%M:%S.%f"), '- connect_and_query with SID-SERIAL#', res[1])

async def main():
    #oracledb.init_oracle_client(lib_dir="/usr/local/oracle/19.19/client64/lib/")
    pool = oracledb.create_pool_async(user="scott", password="tiger", dsn="127.0.0.1/testdb",
                                      min=CONCURRENCY, max=CONCURRENCY,
                                      session_callback=init_session)

    coroutines = [ connect_and_query(pool) for i in range(CONCURRENCY) ]

    start = time.time()
    await asyncio.gather(*coroutines)
    elapsed = time.time() - start
    print("{:04.2f} seconds".format(elapsed))
    await pool.close()

asyncio.run(main())

In thin mode everything works fine. But as soon as I remove the comment from the line with init_oracle_client, the script stops working.
Under Linux I get

Traceback (most recent call last):
  File "src/oracledb/impl/thin/connection.pyx", line 636, in oracledb.thin_impl.AsyncThinConnImpl._connect_with_address
  File "src/oracledb/impl/thin/protocol.pyx", line 597, in _connect_phase_one
AttributeError: 'NoneType' object has no attribute 'encode'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/mmb/p/tt/test.py", line 41, in <module>
    asyncio.run(main())
  File "/usr/lib64/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib64/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/home/mmb/p/tt/test.py", line 36, in main
    await asyncio.gather(*coroutines)
  File "/home/mmb/p/tt/test.py", line 22, in connect_and_query
    async with pool.acquire() as connection:
  File "/home/mmb/p/tt/lib64/python3.9/site-packages/oracledb/connection.py", line 1494, in __aenter__
    await self._connect_coroutine
  File "/home/mmb/p/tt/lib64/python3.9/site-packages/oracledb/connection.py", line 1538, in _connect
    impl = await pool_impl.acquire(params_impl)
  File "src/oracledb/impl/thin/pool.pyx", line 804, in acquire
  File "/usr/lib64/python3.9/asyncio/tasks.py", line 442, in wait_for
    return await fut
  File "src/oracledb/impl/thin/pool.pyx", line 656, in _acquire_helper
  File "src/oracledb/impl/thin/pool.pyx", line 662, in oracledb.thin_impl.AsyncThinPoolImpl._acquire_helper
  File "src/oracledb/impl/thin/pool.pyx", line 658, in oracledb.thin_impl.AsyncThinPoolImpl._acquire_helper
  File "/usr/lib64/python3.9/asyncio/locks.py", line 318, in wait_for
    result = predicate()
  File "src/oracledb/impl/thin/pool.pyx", line 898, in oracledb.thin_impl.PooledConnRequest.fulfill
  File "src/oracledb/impl/thin/pool.pyx", line 760, in oracledb.thin_impl.AsyncThinPoolImpl._process_request
  File "src/oracledb/impl/thin/pool.pyx", line 731, in _create_conn_impl
  File "src/oracledb/impl/thin/connection.pyx", line 947, in connect
  File "src/oracledb/impl/thin/connection.pyx", line 943, in oracledb.thin_impl.AsyncThinConnImpl.connect
  File "src/oracledb/impl/thin/connection.pyx", line 695, in _connect_with_params
  File "src/oracledb/impl/thin/connection.pyx", line 675, in _connect_with_description
  File "src/oracledb/impl/thin/connection.pyx", line 645, in _connect_with_address
  File "/home/mmb/p/tt/lib64/python3.9/site-packages/oracledb/errors.py", line 195, in _raise_err
    raise error.exc_type(error) from cause
oracledb.exceptions.OperationalError: DPY-6005: cannot connect to database (CONNECTION_ID=wRh49H0NDfof/nV9D9RMCA==).
'NoneType' object has no attribute 'encode'

Under Windows, the script hangs for a few seconds and then displays the following

Traceback (most recent call last):
  File "src\\oracledb\\impl/thin/connection.pyx", line 636, in oracledb.thin_impl.AsyncThinConnImpl._connect_with_address
  File "src\\oracledb\\impl/thin/protocol.pyx", line 583, in _connect_phase_one
  File "src\\oracledb\\impl/thin/protocol.pyx", line 715, in _connect_tcp
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 1070, in create_connection
    raise exceptions[0]
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 1050, in create_connection
    sock = await self._connect_sock(
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 961, in _connect_sock
    await self.sock_connect(sock, address)
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\proactor_events.py", line 703, in sock_connect
    return await self._proactor.connect(sock, address)
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 817, in _poll
    value = callback(transferred, key, ov)
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 604, in finish_connect
    ov.getresult()
ConnectionRefusedError: [WinError 1225]  cannot connect to database

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\PycharmProjects\geoPay\test2.py", line 45, in <module>
    asyncio.run(main())
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
    return future.result()
  File "D:\PycharmProjects\geoPay\test2.py", line 40, in main
    await asyncio.gather(*coroutines)
  File "D:\PycharmProjects\geoPay\test2.py", line 26, in connect_and_query
    async with pool.acquire() as connection:
  File "D:\PycharmProjects\geoPay\.venv\lib\site-packages\oracledb\connection.py", line 1494, in __aenter__
    await self._connect_coroutine
  File "D:\PycharmProjects\geoPay\.venv\lib\site-packages\oracledb\connection.py", line 1538, in _connect
    impl = await pool_impl.acquire(params_impl)
  File "src\\oracledb\\impl/thin/pool.pyx", line 804, in acquire
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 442, in wait_for
    return await fut
  File "src\\oracledb\\impl/thin/pool.pyx", line 656, in _acquire_helper
  File "src\\oracledb\\impl/thin/pool.pyx", line 662, in oracledb.thin_impl.AsyncThinPoolImpl._acquire_helper
  File "src\\oracledb\\impl/thin/pool.pyx", line 658, in oracledb.thin_impl.AsyncThinPoolImpl._acquire_helper
  File "C:\Users\mmb\AppData\Local\Programs\Python\Python39\lib\asyncio\locks.py", line 318, in wait_for
    result = predicate()
  File "src\\oracledb\\impl/thin/pool.pyx", line 898, in oracledb.thin_impl.PooledConnRequest.fulfill
  File "src\\oracledb\\impl/thin/pool.pyx", line 760, in oracledb.thin_impl.AsyncThinPoolImpl._process_request
  File "src\\oracledb\\impl/thin/pool.pyx", line 731, in _create_conn_impl
  File "src\\oracledb\\impl/thin/connection.pyx", line 947, in connect
  File "src\\oracledb\\impl/thin/connection.pyx", line 943, in oracledb.thin_impl.AsyncThinConnImpl.connect
  File "src\\oracledb\\impl/thin/connection.pyx", line 695, in _connect_with_params
  File "src\\oracledb\\impl/thin/connection.pyx", line 675, in _connect_with_description
  File "src\\oracledb\\impl/thin/connection.pyx", line 641, in _connect_with_address
  File "D:\PycharmProjects\geoPay\.venv\lib\site-packages\oracledb\errors.py", line 195, in _raise_err
    raise error.exc_type(error) from cause
oracledb.exceptions.OperationalError: DPY-6005: cannot connect to database (CONNECTION_ID=i5SuNLORgrA3rQjzRd2dBQ==).

@migelle74 migelle74 added the bug Something isn't working label Jan 23, 2025
@cjbj
Copy link
Member

cjbj commented Jan 23, 2025

From the doc:

Concurrent programming with asyncio is only supported in python-oracledb Thin mode.

I agree a better error would be nicer.

@migelle74
Copy link
Author

Heh... Oracle 11.2 is pain..

@anthony-tuininga
Copy link
Member

A patch will be forthcoming so that this error is raised instead:

DPY-2053: python-oracledb thin mode cannot be used because thick mode has already been enabled

@anthony-tuininga
Copy link
Member

I have pushed a patch that makes this change and have initated a build from which you can download pre-built development wheels once it completes. You can also build from source if you prefer. If you can test your scenario and confirm the patch works as expected, that would be appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working patch available
Projects
None yet
Development

No branches or pull requests

3 participants