
    $j^              	           d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	  ej
        e          ZdZdZdZ eh d	          Zd
edefdZd
edefdZeeefdededefdZeefde	dedee	         fd            ZdS )zH
Database utility functions for connection management with retry logic.
    N)AsyncIterator)asynccontextmanager)Any   g      ?g      @>   InterfaceErrorDeadlockDetectedErrorTooManyConnectionsErrorConnectionDoesNotExistErrorexcreturnc                     	 ddl }n# t          $ r Y dS w xY wt          | |j                  r)| j        r"| j        d         }t          |dd          dk    S dS )z6Check if an exception is an Oracle ORA-00060 deadlock.r   NFcode<   )oracledbImportError
isinstanceDatabaseErrorargsgetattr)r   r   errs      e/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/engine/db_utils.py_is_oracle_deadlockr      sy       uu#x-.. 038 0hqksFD))R//5s    
c                     t          | t          t          t          j        f          rdS t          |           j        t          v rdS t          |           S )z@Check if an exception is retryable (transient connection issue).T)	r   OSErrorConnectionErrorasyncioTimeoutErrortype__name___RETRYABLE_EXCEPTION_NAMESr   )r   s    r   _is_retryabler!   *   sK    #'2FGHH tCyy777ts###    max_retries
base_delay	max_delayc                 h  K   d}t          |dz             D ]}	  |              d{V c S # t          $ r}t          |          s |}||k     rt          |d|z  z  |          }t	          |          j        dk    st          |          r,t                              d|dz    d|dz    d|dd	           n.t                              d
|dz    d|dz    d| d|dd	           t          j
        |           d{V  n#t                              d|dz    d|            Y d}~d}~ww xY w|)a  
    Execute an async function with exponential backoff retry.

    Args:
        func: Async function to execute
        max_retries: Maximum number of retry attempts
        base_delay: Initial delay between retries (seconds)
        max_delay: Maximum delay between retries (seconds)

    Returns:
        Result of the function

    Raises:
        The last exception if all retries fail
    N      r   us   Deadlock detected during parallel document processing — this is expected and will resolve automatically (attempt /z, retrying in .1fzs)z#Database operation failed (attempt ): . Retrying in s...z Database operation failed after  attempts: )range	Exceptionr!   minr   r   r   loggerwarningr   sleeperror)funcr#   r$   r%   last_exceptionattemptedelays           r   retry_with_backoffr;   3   s     * Nq)) a a	a<<<<<< 	a 	a 	a ## N$$J!W*5yAA77#'>>>BUVWBXBX>NN_$+aK_ _2=/_ _QV^_ _ _    NN7gk 7 7KZ[O 7 7`a 7 7',67 7 7   mE**********_a__\]__```'	a( s   -
D/C-D**D/backend_or_poolc                  K   ddl m} t          | |          st          | dd          rkt	          j                    }d}t          |dz             D ]@}	 |                                 4 d{V }t	          j                    |z
  }|dk    rt                              d|dd	           |W V  	 ddd          d{V   dS # 1 d{V swxY w Y   # t          $ r}t          |          s |}||k     rit          t          d
|z  z  t                    }	t                              d|dz    d|dz    d| d|	dd	           t          j        |	           d{V  n#t                              d|dz    d|            Y d}~:d}~ww xY w|| t	          j                    }fd}
t#          |
|           d{V }t	          j                    |z
  }|dk    rL                                }                                }t                              d|dd| d|            	 |W V                      |           d{V  dS #                     |           d{V  w xY w)a  
    Async context manager to acquire a database connection with retry logic.

    Accepts either a DatabaseBackend or a raw asyncpg.Pool for backward compatibility.

    Usage:
        async with acquire_with_retry(backend) as conn:
            await conn.execute(...)

    Args:
        backend_or_pool: A DatabaseBackend instance or asyncpg.Pool
        max_retries: Maximum number of retry attempts

    Yields:
        A DatabaseConnection (if backend) or asyncpg.Connection (if pool)
    r'   )DatabaseBackend_wraps_backendFNg?z[DB POOL] Slow acquire: z.3fsr(   z!Database acquire failed (attempt r)   r+   r,   r*   r-   zDatabase acquire failed after r.   c                  <   K                                      d {V S )N)acquire)pools   r   rB   z#acquire_with_retry.<locals>.acquire   s'      '''''''r"   )r#   z	s | size=z, idle=)db.baser>   r   r   timer/   rB   r2   r3   r0   r!   r1   DEFAULT_BASE_DELAYDEFAULT_MAX_DELAYr   r4   r5   r;   get_sizeget_idle_sizerelease)r<   r#   r>   startr7   r8   connacquire_timer9   r:   rB   	pool_size	pool_freerC   s                @r   acquire_with_retryrP   c   s     $ )(((((/?33 -%wP`bg7h7h -%	[1_-- 	c 	cGc*2244       #'9;;#6L#d**'U,'U'U'U'UVVVJJJJ                               c c c$Q'' !"[(( 2aj ACTUUENN7GaK 7 7+XY/ 7 7^_ 7 7',67 7 7   "-..........LL!a+PQ/!a!a^_!a!abbbc  		( 	( 	( 	( 	( ([IIIIIIIIIy{{U*$I**,,INNnlnnnQZnnclnnooo	%JJJJ,,t$$$$$$$$$$$$,,t$$$$$$$$$$sJ   C1AC3C
C	CC	C
F#B$FF1I I0)__doc__r   loggingrE   collections.abcr   
contextlibr   typingr   	getLoggerr   r2   DEFAULT_MAX_RETRIESrF   rG   	frozensetr    BaseExceptionboolr   r!   intfloatr;   rP    r"   r   <module>r^      s       ) ) ) ) ) ) * * * * * *      		8	$	$     'Y    	] 	t 	 	 	 	$} $ $ $ $ $ +*(	- -- - 	- - - -` FY @% @%c @% @%^klo^p @% @% @% @% @% @%r"   