: izUdZddlZddlZddlZddlZddlmZmZmZddl m Z ddl m Z GddZ daee ed<d e fd ZdS) z Cache Manager ============= Implementa un semplice LRU cache per query database ripetute. Features: - LRU (Least Recently Used) eviction policy - TTL (Time To Live) per entry scadute - Thread-safe operations - Cache invalidation per dashboard N)AnyOptionalCallable) OrderedDict)loggerc eZdZdZddedefdZdeded efd Zd ed e e fd Z dd ede de efdZ d efdZ defdZdZd efdZddededede ed e f dZd S) CacheManagera Gestore cache con LRU e TTL. Usage: cache = CacheManager(max_size=100, default_ttl=300) # Cache una query key = cache.generate_key('dashboard_tipologie', filters_dict) cached_data = cache.get(key) if cached_data is None: # Esegui query data = execute_query(filters_dict) cache.set(key, data) else: data = cached_data # Invalidate cache per un dashboard cache.invalidate_namespace('dashboard_tipologie') d,max_size default_ttlc||_||_t|_t j|_tjd|d|ddS)z Inizializza il CacheManager. Args: max_size: Numero massimo di entry in cache default_ttl: TTL di default in secondi (300 = 5 minuti) z%CacheManager inizializzato: max_size=z, default_ttl=sN) r r r_cache threadingLock_lockrinfo)selfr r s 0C:\PYTHON\MyICR_Suite\app\utils\cache_manager.py__init__zCacheManager.__init__-sX! &!mm ^%%  bHbbT_bbbccccc namespaceparamsreturnctj|d}tj|}|d|}|S)z Genera una chiave univoca per una query. Args: namespace: Namespace (es. 'dashboard_tipologie', 'dashboard_diritti') params: Parametri della query Returns: Chiave hash univoca T) sort_keys:)jsondumpshashlibmd5encode hexdigest)rrr params_str params_hashkeys r generate_keyzCacheManager.generate_key<sWZ$777 k*"3"3"5"566@@BB **[** rr'c|j5||jvr%tjd| ddddS|j|\}}}t j}||z |kr-tjd||j|= ddddS|j|tjd||cdddS#1swxYwYdS)z Ottiene un valore dalla cache. Args: key: Chiave della entry Returns: Valore cached oppure None se non trovato o scaduto z Cache MISS: NzCache EXPIRED: z Cache HIT: )rrrdebugtime move_to_end)rr'value timestampttl current_times rgetzCacheManager.getNsuZ  $+%% 1C11222         %)K$4 !E9c9;;Li'#-- 4s44555K$         K # #C ( ( ( L,s,, - - -%                  s"CA C2CCCNr-r/c|j5||j}||jvr]t|j|jkr@t t |j}tjd||j|=|tj |f|j|<|j |tjd|d|dddddS#1swxYwYdS)z Salva un valore in cache. Args: key: Chiave della entry value: Valore da cachare ttl: TTL custom (se None usa default) NzCache EVICT (LRU): z Cache SET: z (TTL=zs)) rr rlenr nextiterrr*r+r,)rr'r-r/ oldest_keys rsetzCacheManager.setls3Z ; ;{&$+%%#dk*:*:dm*K*K!$t{"3"344  ?:??@@@K +!&ty{{C8DK  K # #C ( ( ( L9s99#999 : : :# ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;sCCCCc|j5||jvr|j|=tjd|ddddS#1swxYwYdS)zb Invalida una singola entry. Args: key: Chiave da invalidare zCache INVALIDATE: N)rrrr*)rr's r invalidatezCacheManager.invalidatesZ 9 9dk!!K$ 7#77888 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s)>AAc |j5fd|jD}|D] }|j|= |r(tjddt |dddddS#1swxYwYdS)z Invalida tutte le entry di un namespace. Args: namespace: Namespace da invalidare (es. 'dashboard_tipologie') cDg|]}|d|S)r) startswith).0krs r z5CacheManager.invalidate_namespace..s0]]]Aq||yOOO?\?\]a]]]rzCache INVALIDATE namespace 'z':  entries rimossiN)rrkeysrrr3)rrkeys_to_deleter's ` rinvalidate_namespacez!CacheManager.invalidate_namespacesZ p p]]]])9)9););]]]N% % %K$$ p n9nn^I\I\nnnooo p p p p p p p p p p p p p p p p p psAA33A7:A7c|j5t|j}|jt jd|dddddS#1swxYwYdS)zPulisce completamente la cachez Cache CLEAR: r@N)rr3rclearrr)rcounts rrEzCacheManager.clears Z A A $$E K      K???? @ @ @ A A A A A A A A A A A A A A A A A AsAAA"Ac |j5t|j|jt|j|jz dzddt |jdcdddS#1swxYwYdS)ze Ottiene statistiche sulla cache. Returns: Dict con statistiche r z.1f%)sizer utilizationrAN)rr3rr listrA)rs r get_statszCacheManager.get_statssZ  DK(( M"%dk"2"2T]"BS"HOOOOT[--//00                   sA#A88A<?A< query_funcc|||}||}||Stjd||}|||||S)a Utility method per eseguire una query con caching automatico. Args: namespace: Namespace della cache params: Parametri della query query_func: Funzione che esegue la query (callable) ttl: TTL custom Returns: Risultato della query (da cache o freshly executed) Example: def load_data(filters): return database.execute_query(filters) data = cache.cached_query( 'dashboard_tipologie', filters_dict, lambda: load_data(filters_dict), ttl=600 ) NzCache MISS, executing query: )r(r1rr*r7)rrrrMr/r' cached_valuer-s r cached_queryzCacheManager.cached_querysy0 622xx}}  #   @Y@@AAA  eS!!! r)r r )N)__name__ __module__ __qualname____doc__intrstrdictr(rrr1r7r9rCrErLrrPrrr r sy* d d d d d d dc4C$sx}<;;s;3;Xc];;;;8 9c 9 9 9 9pcpppp AAA 4    &&c&4&X&T\]`Ta&mp&&&&&&rr _cache_manager_instancerc@ttddatS)zc Ottiene l'istanza singleton del CacheManager. Returns: CacheManager instance Nr r )r r )rYr rXrrget_cache_managerr[s-&".# # #  #"r)rTr+r!rrtypingrrr collectionsrlogururr rY__annotations__r[rXrrr`s     **********######IIIIIIII\37,/666 #< # # # # # #r