
    E&jK                     "    d dl   G d d      Zy)    )*c                   B    e Zd ZdZd
dZd ZddZddZddZd Z	d Z
y	)CmfCacheClusterVersionStorageu  
    - Размер бакета задается для каждой модели, разные модели не пересекаются
    - Примеры запросов:
        ALL.CmfLogicType.insdel
        ID.CmfLogicType:0628b67a-9c1d-11ef-ae70-00161e14a4f5
        ALL.CmfPerson.rg_member_of
        CmfLists:123.CmfTask.parent_task
    - TODO0: копить события изменения версий и отправлять это при коммите или роллбеке пачкой
    - TODO1: как чистить старую информацию о версиях
    - TODO1: как работает вытеснение по памяти с хештейблами (целиком весь или частично)
    c                     || _         d| j                    | _        d| _        || _        || _        i | _        d | _        y )N	VerStore_F)name
redis_hmap	init_doneuse_bucketsbucket_sizestorageredis_instance)selfr   r   r   s       +./cmf/util/cache_cluster_version_storage.py__init__z&CmfCacheClusterVersionStorage.__init__   sA    	%dii[1&&"    c                 .    t        d| j                   d      | j                         || _        | j                  j	                  | j
                  d      D ci c]  \  }}|j                         t        |      ! c}}| _        d| _	        y c c}}w )NCmfCacheClusterVersionStorage::update)channeli  )countT)
on_server_eventr   
_on_updater   
hscan_iterr	   decodeintr   r
   )r   r   kvs       r   	init_storz'CmfCacheClusterVersionStorage.init_stor   s~    T"@7 STUYUdUde,595H5H5S5STXTcTcko5S5pqca
3q6)q rs   $Bc                     | j                   st        | j                  r|r| j                  |      }| j                  j                  |d      S Nr   )r
   	Exceptionr   _bucket_hashr   get)r   keycacl_bucket_hashs      r   get_versionz)CmfCacheClusterVersionStorage.get_version    sA    ~~O 0##C(C||Q''r   c                 
   | j                   st        | j                  r|r| j                  |      }| j                  j                  | j                  |      }|| j                  |<   t        d| j                   d||i       |S )u:  
        Алгоритм:
        - атомарно увеличиваем версию через Redis
        - обвновляем версию в своем storage
        - оповещаем другие процессы об изменении версий (??? отложено, пачкой)
        r   r   )
r
   r"   r   r#   r   hincrbyr	   r   cmf_emit_server_eventr   )r   r%   r&   vers       r   inc_versionz)CmfCacheClusterVersionStorage.inc_version'   sz     ~~O 0##C(C!!))$//3?S >tyykQTWY\S]^
r   c           
      (   | j                   st        |sy | j                  r3|r1t        t	        |D cg c]  }| j                  |       c}            }| j                  j                         5 }|D ]  }|j                  | j                  |         |j                         }d d d        t        t        |            }|j                         D ]  \  }}|| j                  |<    t        d| j                    d|       |S c c}w # 1 sw Y   fxY w)Nr   r   )r
   r"   r   listsetr#   r   pipeliner)   r	   executedictzipitemsr   r*   r   )r   keysr&   r%   piperesupdatesr+   s           r   inc_version_listz.CmfCacheClusterVersionStorage.inc_version_list8   s    ~~O 0tDT..s3DEFD  ))+ 	!t 3T__c23,,.C	! s4~& 	$HC #DLL	$ >tyykQSZ[ E	! 	!s   D/4DDc                     |j                         D ]6  \  }}| j                  j                  |d      }||kD  s(|| j                  |<   8 y r!   )r4   r   r$   )r   datakwargsr   r   cur_vers         r   r   z(CmfCacheClusterVersionStorage._on_updateI   sE    JJL 	$DAqll&&q!,G7{"#Q	$r   c                    g }|j                  d      D ]  }d|v r|j                  d      \  }}t        |      dk7  rt        d|      |j                  d      r|dd  }t	        |j                  dd      d	      | j                  z  }|j                  | d|d
t        t        | j                               d       |j                  |        dj                  |      S )N.:$   u6   Двойной рассчет _bucket_hash для key=H   -    z0>)
splitlenr"   
startswithr   replacer   appendstrjoin)r   r%   r7   part
model_nameuuidhshs          r   r#   z*CmfCacheClusterVersionStorage._bucket_hashO   s     IIcN 	Dd{#'::c? 
Dt9?#&]Y\X^$_``??3'8D$,,sB/4t7G7GG

j\3r#c$:J:J6K2L1MP.M*NOPJJt	 xx}r   N)Fi  )F)__name__
__module____qualname____doc__r   r   r'   r,   r9   r   r#    r   r   r   r      s*    
#(""$r   r   N)cmf.includer   rV   r   r   <module>rX      s    a ar   