
    3iQ4                        S SK r S SKrS SKJrJrJrJrJrJr  S SK	J
r
JrJr  S SKJr  S SKJrJr  S SKJrJr  S SKJrJrJrJr  S SKJrJrJr  S S	KJr  S S
K J!r!J"r"  Sr#Sr$Sr%Sr& " S S\\5      r' " S S\\5      r( " S S\\5      r)g)    N)AnyCallableDictListOptionalcast)clientconfigwatch)ApiException)EnforceOverridesoverride)RoutingModeSystem)Member
MemberlistMemberlistProviderSegmentDirectory)OpenTelemetryGranularityadd_attributes_to_current_spantrace_method)Segment)assignmurmur3hasher<   chromazchroma.clusterzsvc.cluster.localc                      ^  \ rS rSr% Sr\\S'   S\4U 4S jjr\	S\4S j5       r
\	S\SS	4S
 j5       rS\SS	4S jrSrU =r$ )MockMemberlistProvider   z&A mock memberlist provider for testing_memberlistsystemc                 n   > [         TU ]  U5        [        SSSS9[        SSSS9[        SS	S
S9/U l        g )Naz10.0.0.1node1idipnodebz10.0.0.2node2cz10.0.0.3node3)super__init__r   r    selfr!   	__class__s     m/home/james-whalen/.local/lib/python3.13/site-packages/chromadb/segment/impl/distributed/segment_directory.pyr.   MockMemberlistProvider.__init__#   s>     cjw7cjw7cjw7
    returnc                     U R                   $ Nr    r0   s    r2   get_memberlist%MockMemberlistProvider.get_memberlist+   s    r4   
memberlistNc                     g r7    r0   r<   s     r2   set_memberlist_name*MockMemberlistProvider.set_memberlist_name/   s    r4   c                 F    Xl         U R                   H  nU" U5        M     g)z]Updates the memberlist and calls all registered callbacks. This mocks an update from a k8s CRN)r    	callbacksr0   r<   callbacks      r2   update_memberlist(MockMemberlistProvider.update_memberlist3   s    %HZ  'r4   r8   )__name__
__module____qualname____firstlineno____doc__r   __annotations__r   r.   r   r:   strr@   rF   __static_attributes____classcell__r1   s   @r2   r   r      sm    0
v 
  
     c d  !J !4 ! !r4   r   c                     ^  \ rS rSr% Sr\R                  \S'   \\	   \S'   \\
   \S'   \R                  \S'   \\R                     \S'   \R                  \S'   \R                  \S	'   S
\4U 4S jjr\SU 4S jj5       r\SU 4S jj5       r\SS j5       r\S\
4S j5       r\S\	SS4S j5       rS\
4S jrSS jrS\\	\4   S\
4S jrS\
SS4S jrSrU =r$ ) CustomResourceMemberlistProvider:   zMA memberlist provider that uses a k8s custom resource to store the memberlist_kubernetes_api_memberlist_name_curr_memberlist_curr_memberlist_mutex_watch_thread_kill_watch_thread_done_waiting_for_resetr!   c                 H  > [         TU ]  U5        [        R                  " 5         [        R
                  " 5       U l        S U l        S U l        S U l	        [        R                  " 5       U l        [        R                  " 5       U l        [        R                  " 5       U l        g r7   )r-   r.   r
   load_configr	   CustomObjectsApirU   rY   rV   rW   	threadingLockrX   EventrZ   r[   r/   s     r2   r.   )CustomResourceMemberlistProvider.__init__E   sr     %668! $ $&/nn&6#"+//"3'0'8$r4   r5   Nc                    > U R                   c  [        S5      eU R                  5         U R                  R	                  5         U R                  5         [        TU ]  5       $ )Nz+Memberlist name must be set before starting)rV   
ValueErrorr:   r[   clear_watch_worker_memberlistr-   startr0   r1   s    r2   rg   &CustomResourceMemberlistProvider.startP   sQ      (JKK$$**,%%'w}r4   c                 4  > S U l         S U l        U R                  R                  5         U R                  b  U R                  R                  5         S U l        U R                  R                  5         U R                  R                  5         [        TU ]%  5       $ r7   )
rW   rV   rZ   setrY   joinre   r[   r-   stoprh   s    r2   rm   %CustomResourceMemberlistProvider.stopY   s}     $ $ 	##%)##%!%%'$$**,w|~r4   c           
         U R                   R                  R                  S5      (       d  [        S5      eU R                  (       a  U R
                  R                  5         U R                  R                  [        S[        SU R                  SS/ 0S.S9  U R
                  R                  S	5        [        R                  " S
5        g g )Nallow_resetzResetting the database is not allowed. Set `allow_reset` to true in the config in tests or other non-production environments where reset should be permitted.v1memberlists
MemberListmembers)kindspec)groupversion	namespacepluralnamebodyg      @g      ?)_systemsettingsrequirerd   rV   r[   re   rU   patch_namespaced_custom_objectKUBERNETES_GROUPKUBERNETES_NAMESPACEwaittimesleepr9   s    r2   reset_state,CustomResourceMemberlistProvider.reset_stateg   s    
 ||$$,,];; p    ((..0  ??&.$**(&O @ 
 ((--c2 JJsO# !r4   c                 ^    U R                   c  U R                  5       U l         U R                   $ r7   )rW   _fetch_memberlistr9   s    r2   r:   /CustomResourceMemberlistProvider.get_memberlist   s+      ($($:$:$<D!$$$r4   r<   c                     Xl         g r7   )rV   r?   s     r2   r@   4CustomResourceMemberlistProvider.set_memberlist_name   s     *r4   c                    U R                   R                  [        S[        SU R                   S9n[        [        [        [        4   U5      nSU;  a  / $ [        [        [        [        4   US   5      nU R                  U5      $ )Nrq   rr   )rw   rx   ry   rz   r{   rv   )
rU   get_namespaced_custom_objectr   r   rV   r   r   rN   r   _parse_response_memberlist)r0   api_responseresponse_specs      r2   r   2CustomResourceMemberlistProvider._fetch_memberlist   s    ++HH"* ))* I 
 DcNL9%IT#s(^\&-AB..}==r4   c                    ^  SU 4S jjnT R                   c-  [        R                  " USS9nUR                  5         UT l         g [	        S5      e)Nc                  $  >^ [         R                  " 5       mSUU4S jjn TR                  R                  5       (       d)   U " 5         TR                  R                  5       (       d  M)  g ! [         a  nUR
                  S:X  a    S nANBS nAff = f)Nc            
        > TR                  TR                  R                  [        S[        SSTR
                   3[        S9 GH  n [        [        [        [        4   U 5      n U S   S   n[        [        [        [        4   U5      nTR                     TR                  U5      Tl        S S S 5        TR                  TR                  5        TR                  R                   R#                  S5      (       d  M  TR$                  R'                  5       (       a  M  [)        TR                  5      S:  d  M  TR$                  R+                  5         GM     g ! , (       d  f       N= f)	Nrq   rr   zmetadata.name=)rw   rx   ry   rz   field_selectortimeout_secondsobjectrv   rp   r   )streamrU   list_namespaced_custom_objectr   r   rV   WATCH_TIMEOUT_SECONDSr   r   rN   r   rX   r   rW   _notifyr}   r~   r   r[   is_setlenrk   )eventr   r0   ws     r2   do_watch^CustomResourceMemberlistProvider._watch_worker_memberlist.<locals>.run_watch.<locals>.do_watch   s   XX((FF* 2(%3D4I4I3J#K$9 & E !c3h7E$)(OF$;M$(c3h$GM44040O0O)1- 5 LL!6!67--55mDD $ < < C C E E 5 56:4488:- 54s   E
E&	i  r5   N)r   WatchrZ   r   r   status)r   er   r0   s     @r2   	run_watchLCustomResourceMemberlistProvider._watch_worker_memberlist.<locals>.run_watch   sv    A; ;6 --4466J --4466 	 $ xx3s   A* *
B4B

BT)targetdaemonz"A watch thread is already running.r   )rY   r_   Threadrg   	Exception)r0   r   threads   `  r2   rf   9CustomResourceMemberlistProvider._watch_worker_memberlist   sF    %	N %%%YtDFLLN!'D@AAr4   api_response_specc           	          SU;  a  / $ / nUS    H;  nUS   nSU;   a  US   OSnSU;   a  US   OSnUR                  [        XEUS95        M=     U$ )Nrt   	member_id	member_ip member_node_namer%   )appendr   )r0   r   parsedmr&   r'   r(   s          r2   r   ;CustomResourceMemberlistProvider._parse_response_memberlist   so     --I"9-A;B#.!#3;B,>!,C1'(DMM&BD9:	 .
 r4   c                 :    U R                    H  nU" U5        M     g r7   )rC   rD   s      r2   r   (CustomResourceMemberlistProvider._notify   s    HZ  'r4   )rW   rX   r[   rZ   rU   rV   rY   r   )rH   rI   rJ   rK   rL   r	   r^   rM   r   rN   r   r_   r`   r   ra   r   r.   r   rg   rm   r   r:   r@   r   rf   r   r   r   r   rO   rP   rQ   s   @r2   rS   rS   :   s#   W,,,sm#z**%NN*I,,--!'&__,	9v 	9      6 %
 % %
 +c +d + +>: >/Bb!%c3h	!* ! ! !r4   rS   c                   L  ^  \ rS rSr% \\S'   \R                  \S'   \\	   \S'   \
\S'   S\4U 4S jjr\SU 4S
 jj5       r\SU 4S jj5       r\S\S\S\\   4S j5       r\S\\/S	4   SS	4S j5       r\" S\R2                  5      S\	SS	4S j5       rS\S\\   4S jrSrU =r$ )RendezvousHashSegmentDirectory   _memberlist_providerrX   rW   _routing_moder!   c                 F  > [         TU ]  U5        U R                  [        5      U l        UR
                  R                  S5      nU R                  R                  U5        UR
                  R                  S5      U l        S U l        [        R                  " 5       U l        g )Nworker_memberlist_name%chroma_segment_directory_routing_mode)r-   r.   r   r   r   r~   r@   r   rW   r_   r`   rX   )r0   r!   memberlist_namer1   s      r2   r.   'RendezvousHashSegmentDirectory.__init__   s~     $(LL1C$D! //112JK!!55oF#__443
 !%&/nn&6#r4   r5   Nc                    > U R                   R                  5       U l        U R                   R                  U R                  5        [
        TU ]  5       $ r7   )r   r:   rW   $register_updated_memberlist_callback_update_memberlistr-   rg   rh   s    r2   rg   $RendezvousHashSegmentDirectory.start   sE     $ 9 9 H H J!!FF##	
 w}r4   c                 j   > U R                   R                  U R                  5        [        TU ]  5       $ r7   )r   &unregister_updated_memberlist_callbackr   r-   rm   rh   s    r2   rm   #RendezvousHashSegmentDirectory.stop   s.    !!HH##	
 w|~r4   segmentnc           	         U R                   b  [        U R                   5      S:X  a  [        S5      e[        U[        U R                   5      5      n[	        U R                    Vs/ s H0  o3R
                  S:g  =(       a    [        UR
                  5      S:g  PM2     sn5      =(       a    U R                  [        R                  :H  nU(       aD  [        US   R                  U R                    Vs/ s H  o3R
                  PM     sn[        U5      nOC[        US   R                  U R                    Vs/ s H  o3R                  PM     sn[        U5      n[        U5      n/ nU R                    H  nU=(       a    UR
                  U;   n	U(       + =(       a    UR                  U;   n
U	(       d	  U
(       d  MH  UR                  b2  UR                  S:w  a"  UR                   S3nUR                  U5        M  U R!                  UR                  5      nUR                   SU S["         S[$         S3nUR                  U5        M     U$ s  snf s  snf s  snf )Nr   zMemberlist is not initializedr   
collectionz:50051.)rW   r   rd   minallr(   r   r   NODEr   hexr   r&   rk   r'   r   extract_service_namer   HEADLESS_SERVICE)r0   r   r   r   can_use_node_routingassignmentsassignments_setout_endpointsmemberis_chosen_with_node_routingis_chosen_with_id_routingendpointservice_names                r2   get_segment_endpoints4RendezvousHashSegmentDirectory.get_segment_endpoints   s     (C0E0E,F!,K<==
 3t,,-. D<Q<QR<Qq22#aff+"22<QRS 7""k&6&66 	   %))!%!6!67!6A!67	K !%))#4454!45	K k*++F$G)G ( )(IVYY/-I & +.G.G 99(VYY"_"())F3H!((2#'#<#<VYY#GL"())Al^1=Q<RRSTdSeeklH!((2! ," M S 8 6s   $7I.I
2I
rE   c                     [        5       er7   )NotImplementedError)r0   rE   s     r2   !register_updated_segment_callback@RendezvousHashSegmentDirectory.register_updated_segment_callback:  s     "##r4   z1RendezvousHashSegmentDirectory._update_memberlistr<   c                     U R                      [        SU Vs/ s H  o"R                  PM     sn05        Xl        S S S 5        g s  snf ! , (       d  f       g = f)Nnew_memberlist)rX   r   r&   rW   )r0   r<   r   s      r2   r   1RendezvousHashSegmentDirectory._update_memberlist@  sJ    
 ((*!*#=*QDD*#=> %/!	 )(#= )(s   A	AA	A		
Apod_namec                 l    UR                  S5      n[        U5      S:  a  SR                  US S 5      $ g )N-   )splitr   rl   )r0   r   partss      r2   r   3RendezvousHashSegmentDirectory.extract_service_nameK  s3    s#u:>88E#2J''r4   )rW   rX   r   r   r   )rH   rI   rJ   rK   r   rM   r_   r`   r   r   r   r   r.   r   rg   rm   r   intr   rN   r   r   r   r   r   ALLr   r   rO   rP   rQ   s   @r2   r   r      s   ,,%NN*z**
7v 
7     8W 8 8c 8 8t $ 'D1$	$ $
 ; $$/Z /D /	/S Xc]  r4   r   )*r_   r   typingr   r   r   r   r   r   
kubernetesr	   r
   r   kubernetes.client.restr   	overridesr   r   chromadb.configr   r   chromadb.segment.distributedr   r   r   r    chromadb.telemetry.opentelemetryr   r   r   chromadb.typesr   chromadb.utils.rendezvous_hashr   r   r   r   r   r   r   rS   r   r>   r4   r2   <module>r      s      < < , , / 0 /  
 # @   # & !/1A !8a!'9;K a!Hs%57G sr4   