
    #iT                    (   % S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  \	" \5      r0 rS\S'   \R                   " 5       rSS	 jrSSS jjrSS jrSS jrSqS
\S'   SqS\S'   SS jrSqS\S'   SS jrSS jrSSS jjrSS jrSS jrg) zSimple cache wrapper with Redis primary and in-memory dict fallback.

Tries Redis first. Falls back to an in-memory dict with TTL if Redis
is unavailable or disabled.  Uses JSON serialization for values.
    )annotationsN)Any)
get_logger)get_settingsz#dict[str, tuple[float | None, str]]_memory_storec                \   [            [        R                  U 5      nUc
   SSS5        gUu  p#Ub*  [        R                  " 5       U:  a  [        U 	  SSS5        g [
        R                  " U5      sSSS5        $ ! [
        R                   a     SSS5        gf = f! , (       d  f       g= f)z%Get a value from the in-memory store.N)_lockr   gettime	monotonicjsonloadsJSONDecodeError)keyentry
expires_at
json_values       ?/root/tipsharks/tipsharks-elo-api/packages/core/common/cache.py_memory_getr      s    	!!#&= 
 "'
!dnn&6&Cc" 
	::j) 
 ## 	 
	 
s.   B(BA;;BBBB
B+r   c                    Ub  [         R                  " 5       U-   OSn[           U[        R                  " U[
        S94[        U '   SSS5        g! , (       d  f       g= f)z?Set a value in the in-memory store with optional TTL (seconds).Ndefault)r   r   r	   r   dumpsstrr   )r   valuettlr   s       r   _memory_setr   -   s@    -0_$.."S($J	($**UC*HIc 
s   #A
Ac                p    [            [        R                  U S5        SSS5        g! , (       d  f       g= f)z&Delete a key from the in-memory store.N)r	   r   pop)r   s    r   _memory_deleter    4   s    	#t$ 
s   '
5c                 l    [            [        R                  5         SSS5        g! , (       d  f       g= f)z+Clear all entries from the in-memory store.N)r	   r   clear     r   _memory_clearr%   :   s    	 
s   %
3_redis_clientzbool | None_redis_availablec                    [         SL a  g[        b  [        $ [        5       n U R                  R                  (       d  [
        R                  S5        Sq g SSKnUR                  U R                  R                  SSSS9q[        R                  5         [
        R                  SS	U R                  R                  0S
9  Sq [        $ ! [         a+  n[
        R                  SS[        U5      0S
9  Sq  SnAgSnAff = f)z@Return the global Redis client, or None if unavailable/disabled.FNz@Redis caching is disabled via settings, using in-memory fallbackr   T   )decode_responsessocket_connect_timeoutsocket_timeoutzRedis cache backend activeurlextraz2Redis unavailable, falling back to in-memory cacheerror)r'   r&   r   redisenabledloggerinfofrom_urlr-   ping	Exceptionwarningr   )settings_redisexcs      r   _get_redis_clientr<   H   s     5  ~H>>!!VW NN!#$	 ( 
 	((..,,- 	 	
   @CH% 	 	
 !s   A/C 
C;!C66C;z
str | None_backendc                 p    [         c*  [        5       b  Sq OSq [        R                  SS[         0S9  [         $ )zBReturn the name of the active cache backend ('redis' or 'memory').r1   memoryzCache backend resolvedbackendr.   )r=   r<   r3   r4   r#   r$   r   	get_cacherA   x   s8     *HH,Y4IJOr$   c                   [        5       nUb,   UR                  U 5      nUc  g[        R                  " U5      $ [        U 5      $ ! [         a4  n[
        R                  SS[        U5      0S9  [        U 5      s SnA$ SnAff = f)zwRetrieve a value from cache.

Args:
    key: Cache key.

Returns:
    Deserialized value or None if missing / expired.
Nz$Redis cache_get failed, falling backr0   r.   )	r<   r
   r   r   r7   r3   r8   r   r   )r   clientrawr;   s       r   	cache_getrE      s      F		$**S/C{::c?" s  	$NN6wC>Q   s##		$s"   A A 
B)A>8B>Bc           	     :   Uc  [        5       R                  R                  n[        5       nUb+   UR	                  X[
        R                  " U[        S95        g[        XU5        g! [         a)  n[        R                  SS[        U5      0S9   SnAN;SnAff = f)zStore a value in cache.

Args:
    key: Cache key.
    value: Value to store (must be JSON-serializable).
    ttl: Time-to-live in seconds.  Uses ``settings.redis.ttl_seconds``
         when *ttl* is ``None`` and Redis is the active backend.
Nr   z$Redis cache_set failed, falling backr0   r.   )r   r1   ttl_secondsr<   setexr   r   r   r7   r3   r8   r   )r   r   r   rC   r;   s        r   	cache_setrI      s     {n"".. F	LL4::eS#AB C   	NN6wC>Q  	s   )A' '
B1BBc                z    [        5       nUb   UR                  U 5        g[        U 5        g! [         a     Nf = f)zRemove a single key from cache.N)r<   deleter7   r    )r   rC   s     r   cache_deleterL      sB     F	MM# 3  		s   - 
::c                 t    [        5       n U b   U R                  5         [        5         g! [         a     Nf = f)z4Flush the entire cache (both backends if available).N)r<   flushdbr7   r%   )rC   s    r   cache_clearrO      s:     F	NN O  		s   * 
77)r   r   return
Any | None)N)r   r   r   r   r   z
int | NonerP   None)r   r   rP   rR   )rP   rR   )rP   rQ   )rP   r   )__doc__
__future__r   r   	threadingr   typingr   packages.core.common.loggingr   packages.core.common.settingsr   __name__r3   r   __annotations__Lockr	   r   r   r    r%   r&   r'   r<   r=   rA   rE   rI   rL   rO   r#   r$   r   <module>r\      s    #     3 6	H	  2  	 J% s  $ + $&Z * 	2!2	r$   