python-oracledb icon indicating copy to clipboard operation
python-oracledb copied to clipboard

During using pool in async mode with POOL_GETMODE_TIMEDWAIT see an excess of opened and busy connects over max

Open golubovai opened this issue 1 year ago • 2 comments

Hello! This test case can be used to clarify what is going:

async def test_5529(self):
        "5529 - ensure max limit of pool is not exceeded"
        proc_name = test_env.get_sleep_proc_name()
        async def work(pool: oracledb.AsyncConnectionPool):
            while True:
                conn = None
                try:
                    conn = await pool.acquire()
                    async with conn.cursor() as cursor:
                        await cursor.callproc(proc_name, [5])
                    break
                except Exception as e:
                    continue
                finally:
                    if conn is not None:
                        await conn.close()
                    
        pool = test_env.get_pool_async(min=0, max=2, increment=1, wait_timeout=500, getmode=oracledb.POOL_GETMODE_TIMEDWAIT)
        for _ in range(20):
            asyncio.create_task(work(pool))
        for _ in range(10):
            await asyncio.sleep(0.5)
            print(f'opened: {pool.opened} busy: {pool.busy} max: {pool.max}')
            self.assertTrue(pool.busy <= pool.max)

golubovai avatar Aug 29 '24 08:08 golubovai

It's this place in source:

async def _process_request(self, PooledConnRequest request):
        """
        Processes a request.
        """
        cdef BaseThinConnImpl conn_impl
        try:
            if request.requires_ping:
                try:
                    request.conn_impl.set_call_timeout(self._ping_timeout)
                    await request.conn_impl.ping()
                    request.conn_impl.set_call_timeout(0)
                    request.completed = True
                except exceptions.Error:
                    request.conn_impl._force_close()
                    request.conn_impl = None
            else:
                conn_impl = await self._create_conn_impl(request.params)
                if request.conn_impl is not None:
                    request.conn_impl._force_close()
                request.conn_impl = conn_impl
                request.conn_impl._is_pool_extra = request.is_extra
                request.completed = True
        except Exception as e:
            request.exception = e
        finally:
            request.in_progress = False
            request.bg_processing = False

On else we create new connection by non waiting request with no respect to value of current opened connections because condition in _get_next_request push it to process:

if not request.waiting \
                    or request.requires_ping \
                    or request.is_replacing \
                    or request.is_extra \
                    or self._open_count < self.max:

I think we can change this to: elif self._open_count < self.max or elif request.waiting and self._open_count < self.max depending on our wish to account timeouted request in connect creation.

golubovai avatar Aug 29 '24 09:08 golubovai

The recent changes I pushed to the pool code should resolve this situation as well. Can you confirm, please?

anthony-tuininga avatar Oct 26 '24 17:10 anthony-tuininga

@golubovai python-oracledb 2.5 has the change @anthony-tuininga made. Can you try it out and let us know whether it resolves your problem?

cjbj avatar Nov 07 '24 02:11 cjbj

Hi. I have a similar situation. Updating to the latest version did not work. With long running queries, the number of connections in the pool exceeds the maximum limit.

rreboot avatar Nov 15 '24 12:11 rreboot

Can you provide more detail of your situation? What are the pool configuration parameters you are using? What are you using to determine the number of connections in the pool? Can you define "long running"? Anything else you can provide that would help determine the source of the issue? Ideally a test case that proves what you are saying would be helpful!

anthony-tuininga avatar Nov 15 '24 20:11 anthony-tuininga

This issue has been automatically marked as inactive because it has not been updated recently. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Apr 26 '25 14:04 stale[bot]

This issue has been automatically closed because it has not been updated for a month.

stale[bot] avatar Jul 19 '25 06:07 stale[bot]