
    Σi$                     j   d Z ddlZddlZddlZddlmZ  ej                  dd      Z e ej                  dd            Z	 ej                  dd	      Z
 ej                  d
d      Z ej                  dd	      Z ej                  dd      Z e ej                  dd            Z ej                  dd      Z ej                  dd      Z e ej                  dd            Z ej                  dd      Z ej                  dd      j'                         dk(  ZdZdZd Z G d d      Z e       Zy) u  
AIVA RLM Nexus — Centralized Connection Factory
Story 1.05 — Track A

Single source of truth for PostgreSQL, Redis, and Qdrant connections.
All connections point to Elestio infrastructure. Includes health check and retry.

RULE COMPLIANCE:
  - Rule 7: No SQLite — all storage uses Elestio Postgres/Redis/Qdrant
  - Rule 6: E: drive only — module lives at /mnt/e/genesis-system/core/db/
    N)OptionalPG_HOSTz(postgresql-genesis-u50607.vm.elestio.appPG_PORT25432PG_USERpostgresPG_PASSzCiBjh6LM7Yuqkq-jo2r7eQDwPG_DB
REDIS_HOSTz#redis-genesis-u50607.vm.elestio.app
REDIS_PORT26379
REDIS_PASSze2ZyYYr4oWRdASI2CaLc-QDRANT_HOSTz"qdrant-b3knu-u50607.vm.elestio.appQDRANT_PORT6333QDRANT_API_KEY@7b74e6621bd0e6650789f6662bca4cbf4143d3d1d710a0002b3b563973ca6876QDRANT_HTTPStrue   g      ?c                 B     t        j                          fd       }|S )zKRetry a connection function up to MAX_RETRIES times with RETRY_DELAY sleep.c                     d }t        dt        dz         D ]  }	  | i |c S  t        j                   dt         d|       |# t        $ r.}|}|t        k  rt        j                  t
               Y d }~cd }~ww xY w)N   z failed after z
 retries: )rangeMAX_RETRIES	ExceptiontimesleepRETRY_DELAYConnectionError__name__)argskwargs
last_errorattemptexcfuncs        ,/mnt/e/genesis-system/core/db/connections.pywrapperz_retry.<locals>.wrapper3   s    *.
Qa0 	,G,T,V,,	, }}o^K=
:,O
		  , 
[(JJ{+,s   A	A?$A::A?)	functoolswraps)r'   r)   s   ` r(   _retryr,   1   s%    __T  N    c                   \    e Zd ZdZd
dZed        Zed        Zed        Zde	fdZ
d
d	Zy)ConnectionFactoryz
    Single source of truth for all Elestio database connections.

    Lazy-initialises each connection on first access and caches it.
    Call close_all() to release connections when done (e.g. in teardown).
    returnNc                 .    d | _         d | _        d | _        y )N)_pg_conn_redis_client_qdrant_clientselfs    r(   __init__zConnectionFactory.__init__O   s    !"r-   c                     ddl }| j                  | j                  j                  rA|j                  t        t
        t        t        t        d      | _        d| j                  _	        | j                  S )z
        Return a live psycopg2 connection to Elestio PostgreSQL.
        Re-opens if the cached connection has been closed.
        Retries up to MAX_RETRIES times on failure.
        r   N
   hostportuserpassworddatabaseconnect_timeoutF)
psycopg2r2   closedconnectr   r   r   r	   r
   
autocommit)r6   rA   s     r(   get_postgreszConnectionFactory.get_postgresX   s^     	== DMM$8$8$,,  " - DM (-DMM$}}r-   c                     ddl }| j                  (|j                  t        t        t
        ddd      | _        | j                  j                          | j                  S )z
        Return a connected redis.Redis client pointed at Elestio Redis.
        PINGs the server to confirm liveness.
        Retries up to MAX_RETRIES times on failure.
        r   NTr9   )r;   r<   r>   decode_responsessocket_timeoutsocket_connect_timeout)redisr3   Redisr   r   r   ping)r6   	redis_libs     r(   	get_rediszConnectionFactory.get_redisr   s[     	"%!*#!%!') "1 "D 	!!!!r-   c                     ddl m} | j                  /t        t        dt
        d}t        r	t        |d<    |di || _        | j                  S )zx
        Return a QdrantClient connected to Elestio Qdrant.
        Retries up to MAX_RETRIES times on failure.
        r   QdrantClientr9   r;   r<   timeouthttpsapi_key )qdrant_clientrQ   r4   r   r   r   r   )r6   rQ   r#   s      r(   
get_qdrantzConnectionFactory.get_qdrant   sQ     	/&##%	F $2y!"."8"8D"""r-   c                    dddd}	 ddl }|j                  t        t        t        t
        t        d      }|j                         }|j                  d       |j                         d   dk(  sJ |j                          |j                          d	|d
<   	 ddl}|j                  t        t        t         dd      }|j#                          |j                          d	|d<   	 ddlm} t(        t*        dt,        d}t.        r	t.        |d<    |di |}|j1                          d	|d<   |S # t        $ r Y w xY w# t        $ r Y bw xY w# t        $ r Y |S w xY w)a+  
        Probe each service with a lightweight command.

        Returns:
            {"postgres": bool, "redis": bool, "qdrant": bool}

        A False value means the service is unreachable or returned an error;
        it does NOT raise an exception so callers can act on partial health.
        F)r   rJ   qdrantr   N   r:   zSELECT 1r   Tr   )r;   r<   r>   rH   rI   rJ   rP   rR   rU   rZ   rV   )rA   rC   r   r   r   r	   r
   cursorexecutefetchonecloser   rJ   rK   r   r   r   rL   rW   rQ   r   r   r   r   get_collections)r6   resultrA   probecurrM   rQ   r#   s           r(   health_checkzConnectionFactory.health_check   sg    $euE	$$7w !	 % E ,,.CKK
#<<>!$)))IIKKKM!%F:
	%OOj# '(	 $ E JJLKKM"F7O
	2 $#%	F $2y! *6*E!!##F8 M  		   		&  		s8   BD) AD8 "AE )	D54D58	EE	EEc                 2   | j                   1| j                   j                  s	 | j                   j                          | j                  	 | j                  j                          d| _         d| _        d| _        y# t        $ r Y Hw xY w# t        $ r Y 0w xY w)z)Close and release all cached connections.N)r2   rB   r_   r   r3   r4   r5   s    r(   	close_allzConnectionFactory.close_all   s    ==$T]]-A-A##% )""((*
 "!"    s#   A; B
 ;	BB
	BB)r0   N)r!   
__module____qualname____doc__r7   r,   rE   rN   rX   dictrd   rf   rV   r-   r(   r/   r/   G   s\    #  2 " "4 # #2Bd BP#r-   r/   )ri   osr   r*   typingr   getenvr   intr   r   r	   r
   r   r   r   r   r   r   lowerr   r   r   r,   r/   connectionsrV   r-   r(   <module>rq      sB  
 
    "))II
J
ibii	7+
,
"))Iz
*
"))I9
:
"))Gz
* RYY|%JK
<12
RYY|%<=
 =-QRYRYY}f56+-op>V4::<F ,y# y#F  !r-   