
    Ii                    ^   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKJ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  SS
KJ r   SSK!J"r"  SSK#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  SSK,J-r-  SSK.J/r/J0r0J1r1  SSK2J3r3J4r4J5r5J6r6J7r7  SSK8J9r9  SSK:J;r;  SSK<J=r=J>r>J?r?J@r@JArA  SSKBJCrCJDrDJErEJFrFJGrG  \(       a  SSKHJIrI  SSKJJKrK  SSKLJMrMJNrN  SrO\P" \" \Q5      R                  5      rSS S jrT " S S5      rU " S S5      rV      S!S jrWS"S jrX S#     S$S jjrYg)%z<Internal class to monitor a topology of one or more servers.    )annotationsN)Path)TYPE_CHECKINGAnyCallableMappingOptionalcast)_csotcommonhelpers_shared)periodic_executor)_ServerSession_ServerSessionPool)
SrvMonitor)Pool)Server)ConnectionFailureInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailurePyMongoErrorServerSelectionTimeoutError
WriteError)Hello)_ACondition_ALock_create_lock)_SDAM_LOGGER_SERVER_SELECTION_LOGGER
_debug_log_SDAMStatusMessage_ServerSelectionStatusMessage)PoolOptions)ServerDescription)	Selectionany_server_selectorarbiter_server_selectorsecondary_server_selectorwritable_server_selector)SRV_POLLING_TOPOLOGIESTOPOLOGY_TYPETopologyDescription)_updated_topology_description_srv_pollingupdated_topology_description)ObjectId)TopologySettings)ClusterTime_AddressFc                    U " 5       nU(       d  g  UR                  5       nUu  p4U" U6   M  ! [        R                   a     gf = f)NFT)
get_nowaitqueueEmpty)	queue_refqeventfnargss        C/venv/lib/python3.13/site-packages/pymongo/asynchronous/topology.pyprocess_events_queuer?   R   sT    A
	LLNE HBI  {{ 	
 	s   - AAc                     \ rS rSrSrS0S jrS1S jrS2S jr   S3           S4S jjr            S5S jr	    S6             S7S	 jjr
    S6             S7S
 jjr  S8         S9S jjr  S:       S;S jjr  S:       S;S jjrS<S jrS<S jrS=S jrS>S jrS?S jr    S@S jrSAS jrSAS jrSBS jrSCS jrSCS jrSDSES jjrSFS jrS1S jrS1S jr\SGS j5       rSHS jr SIS jr!SJS  jr"SKS! jr#S1S" jr$SLS# jr%SMS$ jr&SMS% jr'S1S& jr(S1S' jr)SNS( jr*SNS) jr+SOS* jr,SPS+ jr-SQS, jr.SRS- jr/SSS. jr0S/r1g)TTopologyc   z*Monitor a topology of one or more servers.c           	     
  ^ UR                   U l         UR                  R                  U l        U R                  S L=(       a    U R                  R                  U l        U R                  S L=(       a    U R                  R                  U l        S U l        S U l	        U R
                  (       d  U R                  (       a  [        R                  " SS9U l        [        R                  " [        R                  5      (       a'  [!        [        U R                   ["        R$                  S9  U R                  (       aK  U R                  c   eU R                  R'                  U R                  R(                  U R                   445        Xl        [-        UR/                  5       UR1                  5       UR2                  S S U5      nX l        [-        [6        R8                  0 S S S U R*                  5      nU R                  (       aV  U R                  c   eU R                  R'                  U R                  R:                  X0R4                  U R                   445        [        R                  " [        R                  5      (       a3  [!        [        U R                   UU R4                  ["        R<                  S9  UR>                   H  nU R
                  (       aK  U R                  c   eU R                  R'                  U R                  R@                  X@R                   445        [        R                  " [        R                  5      (       d  M  [!        [        U R                   US   US   ["        RB                  S9  M     [E        URG                  5       5      U l$        SU l%        SU l&        [O        5       n[Q        U5      U l)        [U        U R*                  RW                  U5      5      U l,        0 U l-        S U l.        S U l/        [a        5       U l1        U R
                  (       d  U R                  (       a  U R                  c   eSU4S	 jjn[d        Rf                  " [h        Rj                  [h        Rl                  US
S9n[n        Rp                  " U R                  URr                  5      mXpl	        URu                  5         S U l;        U R*                  Rx                  b7  U R*                  Rz                  (       d  [}        X R*                  5      U l;        g g g )Nd   )maxsize
topologyIdmessagerG   previousDescriptionnewDescriptionrH   r      )rG   
serverHost
serverPortrH   Fc                 "   >#    [        T 5      $ 7fN)r?   )weaks   r>   target!Topology.__init__.<locals>.target   s     +D11s   pymongo_events_thread)intervalmin_intervalrR   name)returnbool)?_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr7   Queuer    isEnabledForloggingDEBUGr"   r#   START_TOPOLOGYputpublish_topology_opened	_settingsr.   get_topology_typeget_server_descriptionsreplica_set_name_descriptionr-   Unknown$publish_topology_description_changedTOPOLOGY_CHANGEseedspublish_server_openedSTART_SERVERlistserver_descriptions_seed_addresses_opened_closedr   r   _lockr   condition_class
_condition_servers_pid_max_cluster_timer   _session_poolr   PeriodicExecutorr   EVENTS_QUEUE_FREQUENCYMIN_HEARTBEAT_INTERVALweakrefrefcloseopen_srv_monitorfqdnload_balancedr   )	selftopology_settingstopology_description
initial_tdseedr{   rR   executorrQ   s	           @r>   __init__Topology.__init__f   s   -::+99JJ#d:at?a?a??$6_4??;_;_ &*4#3#3 ;;s3DL$$W]]33,,*99 <<+++LLdooEEHYHYG[\]*2//1557.. 
 1(!!2tT4

 <<+++LLOOHH!2!2D4E4EF $$W]]33,,$.#00*:: &++D##||///  $//"G"G$PaPaIb!cd((77 #00#Aw#Aw.;; ,  $$8$L$L$NOE]
%dnn&D&DU&KL02#'	8</14#3#3<<+++2 )9966#::,	H ;;t||X^^<D%-"MMO >>*4>>3O3O *4 @D 4P*    c                  #    [         R                  " 5       nU R                  c  Xl        OXR                  :w  a  Xl        [        R                  SS S:  a
  S[
        40nOSS0n[        R                  "  S0 UD6  U R                   ISh  vN   U R                  R                  5        H  nUR                  5       I Sh  vN   M     U R                  R                  5         SSS5      ISh  vN   U R                   ISh  vN   U R                  5       I Sh  vN   SSS5      ISh  vN   g N Nr NF! , ISh  vN  (       d  f       N[= f NM N7 N)! , ISh  vN  (       d  f       g= f7f)a  Start monitoring, or restart after a fork.

No effect if called multiple times.

.. warning:: Topology is shared among multiple threads and is protected
  by mutual exclusion. Using Topology from a process other than the one
  that initialized it will emit a warning and may result in deadlock. To
  prevent this from happening, AsyncMongoClient must be created after any
  forking.

N   )      skip_file_prefixes
stacklevel   )zAsyncMongoClient opened before fork. May not be entirely fork-safe, proceed with caution. See PyMongo's documentation for details: https://www.mongodb.com/docs/languages/python/pymongo-driver/current/faq/#is-pymongo-fork-safe-)osgetpidr   sysversion_info_pymongo_dirwarningswarnr{   r~   valuesr   r   reset_ensure_opened)r   pidkwargsservers       r>   r   Topology.open   s     iik99IIII#w..@&*MM)  zzz"mm224F ,,.(( 5 ""((* "z :::%%''' :: " ) "zzz ' :::s   BE3D3E31D9D5"D9%E30D71E3EE3	EEE"E3-E.E35D97E39E?E EE3EE3E0E" E0,E3c                b    [         R                  " 5       nUc  U R                  R                  $ U$ rP   )r   	remainingrk   server_selection_timeout)r   timeouts     r>   get_server_selection_timeout%Topology.get_server_selection_timeout   s(    //#?>>:::r   Nc           
     v  #    Uc  U R                  5       nOUnU R                   ISh  vN   U R                  XX%U5      I Sh  vN nU Vs/ s H,  n[        [        U R                  UR                  5      5      PM.     snsSSS5      ISh  vN   $  Nj NQs  snf  N! , ISh  vN  (       d  f       g= f7f)a2  Return a list of Servers matching selector, or time out.

:param selector: function that takes a list of Servers and returns
    a subset of them.
:param operation: The name of the operation that the server is being selected for.
:param server_selection_timeout: maximum seconds to wait.
    If not provided, the default value common.SERVER_SELECTION_TIMEOUT
    is used.
:param address: optional server address to select.

Calls self.open() if needed.

Raises exc:`ServerSelectionTimeoutError` after
`server_selection_timeout` if no matching servers are found.
N)r   r{   _select_servers_loopr
   r   get_server_by_addressaddress)	r   selector	operationr   r   operation_idserver_timeoutrw   sds	            r>   select_serversTopology.select_servers   s     . $+!>>@N5N:::(,(A(A)7) #
 PcObVT77

CDOb ::# :::sh   'B9BB9BBB3B BB9BB9BBB9B6%B(&B62B9c                  #    [         R                  " 5       nXb-   nSn[        R                  " [        R
                  5      (       aI  [        [        [        R                  UUUU R                  U R                  R                  R                  S9  U R                  R                  XU R                  R                  S9n	U	(       Gd  US:X  d  Xg:  a  [        R                  " [        R
                  5      (       aY  [        [        [        R                   UUUU R                  U R                  R                  R                  U R#                  U5      S9  [%        U R#                  U5       SU SU R                  < 35      eU(       dk  [        [        [        R&                  UUUU R                  U R                  R                  R                  [)        U[         R                  " 5       -
  5      S9  S	nU R+                  5       I S
h  vN   U R-                  5         U R.                  R1                  [2        R4                  5      I S
h  vN   U R                  R7                  5         [         R                  " 5       nU R                  R                  XU R                  R                  S9n	U	(       d  GM  U R                  R7                  5         U	$  N N7f)z7select_servers() guts. Hold the lock when calling this.F)rH   r   r   operationIdtopologyDescriptionclientId)custom_selectorr   )rH   r   r   r   r   r   failurez, Timeout: zs, Topology Description: )rH   r   r   r   r   r   remainingTimeMSTN)time	monotonicr!   re   rf   rg   r"   r$   STARTEDdescription_topology_settingsrZ   ro   apply_selectorrk   server_selectorFAILED_error_messager   WAITINGintr   _request_check_allr}   waitr   r   check_compatible)
r   r   r   r   r   r   nowend_timelogged_waitingrw   s
             r>   r   Topology._select_servers_loop#  sT     nn=#00??(5==!#($($4$4))<<II #//>>t~~/M/M ? 
 &!|s~+88GG0 = D D!)"+$0,0,<,<!%!1!1!D!D!Q!Q $ 3 3H =	 2**845[	Ibcgcscsbvw  ",9AA%' ,(,(8(8!--@@MM$'4>>3C(C$D	 "&%%'''##% //&&v'D'DEEE..0.."C"&"3"3"B"B4>>3Q3Q #C #S &%Z 	**,"" ( Fs,   HKKA KKA(K2KKc                  #    U R                  XX4U5      I S h  vN n[        Xu5      n[        U5      S:X  a  US   $ [        R                  " US5      u  pUR
                  R                  U	R
                  R                  ::  a  U$ U	$  Nn7f)NrL   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
r   r   r   r   r   deprioritized_serversr   serversserver1server2s
             r>   _select_serverTopology._select_servero  s      ++!9L
 
 "'Aw<11:!==!4<<''7<<+G+GGNN
s   B
BA/B
c                  #    U R                  UUUUUUS9I Sh  vN n[        R                  " 5       (       a*  [        R                  " UR                  R
                  5        [        R                  " [        R                  5      (       ay  [        [        [        R                  UUUU R                  U R                  R                  R                  UR                  R                  S   UR                  R                  S   S9	  U$  N7f)zALike select_servers, but choose a random server if several match.r   Nr   rL   )rH   r   r   r   r   r   rM   rN   )r   r   get_timeoutset_rttr   min_round_trip_timer!   re   rf   rg   r"   r$   	SUCCEEDEDr   rZ   r   )r   r   r   r   r   r   r   r   s           r>   select_serverTopology.select_server  s      **$!% + 
 
 MM&,,@@A#00??(5??!#($($4$4))<<II!--55a8!--55a8
 -
s   D	DC-D	c                L   #    U R                  [        UUUUS9I Sh  vN $  N7f)a  Return a Server for "address", reconnecting if necessary.

If the server's type is not known, request an immediate check of all
servers. Time out after "server_selection_timeout" if the server
cannot be reached.

:param address: A (host, port) pair.
:param operation: The name of the operation that the server is being selected for.
:param server_selection_timeout: maximum seconds to wait.
    If not provided, the default value
    common.SERVER_SELECTION_TIMEOUT is used.
:param operation_id: The unique id of the current operation being performed. Defaults to None if not provided.

Calls self.open() if needed.

Raises exc:`ServerSelectionTimeoutError` after
`server_selection_timeout` if no matching servers are found.
r   N)r   r(   )r   r   r   r   r   s        r>   select_server_by_address!Topology.select_server_by_address  s8     2 ''$% ( 
 
 	
 
s   $"$c                  #    U R                   nUR                  UR                     n[        XQ5      (       a  g[	        U R                   U5      nUR
                  (       d/  UR                  (       al  UR                  [        R                  :X  aN  U R                  R                  UR                  5      nU(       a"  UR                  R                  5       I Sh  vN   XQ:H  nU R                  (       a^  U(       dW  U R                  c   eU R                  R!                  U R"                  R$                  XQUR                  U R&                  445        X`l         U R)                  5       I Sh  vN   U R+                  UR,                  5        U R.                  (       a]  U(       dV  U R                  c   eU R                  R!                  U R"                  R0                  X@R                   U R&                  445        [2        R4                  " [6        R8                  5      (       a:  U(       d3  [;        [2        U R&                  UU R                   [<        R>                  S9  U R@                  (       a^  UR                  [        RB                  :X  a@  U R                   R                  [D        ;  a"  U R@                  RG                  5       I Sh  vN   U(       aM  U R                  R                  UR                  5      nU(       a!  UR                  RI                  US9I Sh  vN   U RJ                  RM                  5         g GN` GN Ny N'7f)zYProcess a new ServerDescription on an opened topology.

Hold the lock when calling this.
NrI   )interrupt_connections)'ro   _server_descriptionsr   _is_stale_server_descriptionr0   is_readableis_server_type_knowntopology_typer-   Singler~   getr   readyr_   rb   ri   r]   "publish_server_description_changedrZ   _update_servers_receive_cluster_time_no_lockcluster_timera   rq   r    re   rf   rg   r"   r#   rr   r   rp   r,   r   r   r}   
notify_all)	r   server_description
reset_poolr   td_oldsd_oldnew_tdr   suppress_events	            r>   _process_changeTopology._process_change  sy     "",,-?-G-GH'CC-d.?.?AST))338L8LP]PdPd8d]]&&'9'A'ABFkk'')))5<<+++LLOOFF1C1K1KTM^M^_ #""$$$**+=+J+JKN<<+++LLOOHH..0A0AB $$W]]33N,,$*#00*::   M$9$99!!//7MM##))+++ ]]&&'9'A'ABFkk''>S'TTT 	""$c * 	%6 , UsK   CML8BM)L;*EML>AMM  M;M>M Mc                @  #    U R                    ISh  vN   U R                  (       aD  U R                  R                  UR                  5      (       a  U R                  XU5      I Sh  vN   SSS5      ISh  vN   g Nj N N	! , ISh  vN  (       d  f       g= f7f)z>Process a new ServerDescription after an hello call completes.N)r{   ry   ro   
has_serverr   r  )r   r   r   r   s       r>   	on_changeTopology.on_change  sh      ::: || 1 1 < <=O=W=W X X**+=K`aaa :: b :::sW   BA>BAB(B )B-B8B9B BBB
BBBc                @  #    U R                   nUR                  [        ;  a  g[        U R                   U5      U l         U R	                  5       I Sh  vN   U R
                  (       aV  U R                  c   eU R                  R                  U R                  R                  X R                   U R                  445        [        R                  " [        R                  5      (       a4  [        [        U R                  UU R                   [         R"                  S9  gg N7f)zOProcess a new seedlist on an opened topology.
Hold the lock when calling this.
NrI   )ro   r   r,   r/   r   ra   rb   ri   r]   rq   rZ   r    re   rf   rg   r"   r#   rr   )r   seedlistr   s      r>   _process_srv_updateTopology._process_srv_update%  s      ""'==EdFWFWYab""$$$<<+++LLOOHH..0A0AB $$W]]33,,$*#00*:: 4 	%s   ADDC
Dc                   #    U R                    ISh  vN   U R                  (       a  U R                  U5      I Sh  vN   SSS5      ISh  vN   g N? N N	! , ISh  vN  (       d  f       g= f7f)z?Process a new list of nodes obtained from scanning SRV records.N)r{   ry   r	  )r   r  s     r>   on_srv_updateTopology.on_srv_updateA  sB      :::||..x888 ::8 :::sT   A3AA3&AAAA3AA3AA3A0A" A0,A3c                8    U R                   R                  U5      $ )a"  Get a Server or None.

Returns the current version of the server immediately, even if it's
Unknown or absent from the topology. Only use this in unittests.
In driver code, use select_server_by_address, since then you're
assured a recent view of the server's type and wire protocol version.
)r~   r   r   r   s     r>   r   Topology.get_server_by_addressH  s     }}  ))r   c                    XR                   ;   $ rP   )r~   r  s     r>   r  Topology.has_serverR  s    --''r   c                Z  #    U R                    ISh  vN   U R                  R                  nU[        R                  :w  a   SSS5      ISh  vN   g[        U R                  5       5      S   R                  sSSS5      ISh  vN   $  Nw N> N	! , ISh  vN  (       d  f       g= f7f)z!Return primary's address or None.Nr   )r{   ro   r   r-   ReplicaSetWithPrimaryr+   _new_selectionr   )r   r   s     r>   get_primaryTopology.get_primaryU  sh      ::: --;;M C CC ::
 ,D,?,?,AB1EMM :::::sb   B+BB+,BB+BB+%B9B+BB+B+B+B(BB($B+c                  #    U R                    ISh  vN   U R                  R                  nU[        R                  [        R
                  4;  a  [        5       sSSS5      ISh  vN   $ [        U" U R                  5       5      5       Vs1 s H  o3R                  iM     snsSSS5      ISh  vN   $  N NQs  snf  N! , ISh  vN  (       d  f       g= f7f)z+Return set of replica set member addresses.N)
r{   ro   r   r-   r  ReplicaSetNoPrimarysetiterr  r   )r   r   r   r   s       r>   _get_replica_set_members!Topology._get_replica_set_members_  s     
 ::: --;;M3311%  u :: *.ht7J7J7L.M)NO)N2JJ)NO :: P :::su   CB7CACC'B9(C-!CB;#C%C1C 2C9C;C CCC	CCc                H   #    U R                  [        5      I Sh  vN $  N7f)z"Return set of secondary addresses.N)r  r*   r   s    r>   get_secondariesTopology.get_secondariesn  s     223LMMMM   " "c                H   #    U R                  [        5      I Sh  vN $  N7f)z Return set of arbiter addresses.N)r  r)   r  s    r>   get_arbitersTopology.get_arbitersr  s     223JKKKKr"  c                    U R                   $ )z1Return a document, the highest seen $clusterTime.r   r  s    r>   max_cluster_timeTopology.max_cluster_timev  s    %%%r   c                p    U(       a/  U R                   (       a  US   U R                   S   :  a  Xl         g g g )NclusterTimer'  r   r   s     r>   r   &Topology._receive_cluster_time_no_lockz  s;      **.1G1G1VV)5& W	 r   c                   #    U R                    IS h  vN   U R                  U5        S S S 5      IS h  vN   g  N& N! , IS h  vN  (       d  f       g = f7frP   )r{   r   r,  s     r>   receive_cluster_timeTopology.receive_cluster_time  s+     :::..|< :::::s<   A:A>A<AAAAAAc                   #    U R                    ISh  vN   U R                  5         U R                  R                  U5      I Sh  vN   SSS5      ISh  vN   g NH N N	! , ISh  vN  (       d  f       g= f7f)z=Wake all monitors, wait for at least one to check its server.N)r{   r   r}   r   )r   	wait_times     r>   request_check_allTopology.request_check_all  sI     :::##%//&&y111 ::1 :::sV   A<AA</A"AA"A<A A<A" A<"A9(A+)A95A<c                    U R                   R                  [        R                  :X  a  U R                   R                  $ U R                   R
                  $ )znReturn a list of all data-bearing servers.

This includes any server that might be selected for an operation.
)ro   r   r-   r   known_serversreadable_serversr  s    r>   data_bearing_serversTopology.data_bearing_servers  sB    
 **m.B.BB$$222  111r   c           	     b  #    / nU R                    IS h  vN   U R                  5        HP  nU R                  UR                     nUR	                  X3R
                  R                  R                  5       45        MR     S S S 5      IS h  vN   U H)  u  p4 UR
                  R                  U5      I S h  vN   M+     g  N N6! , IS h  vN  (       d  f       NK= f N'! [         aD  n[        USUSS 5      nU R                  UR                  R                  U5      I S h  vN    e S nAff = f7f)Nr   F)r{   r8  r~   r   appendr   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )r   r   r   r   
generationexcctxs          r>   update_poolTopology.update_pool  s     ::://1rzz2(C(C(EFG 2 : #*Fkk66zBBB #* ::: C #CJtD''(:(:(B(BCHHHs   D/B>D/A%C>D/	C 
D/C4C5C9D/ D/CC	CD/C
D,(8D' D#!D''D,,D/c                  #    U R                    ISh  vN   U R                  nU R                  R                  5        H  nUR	                  5       I Sh  vN   M     U R                  R                  5       U l        U R                  R                  5       R                  5        H)  u  p4X0R                  ;   d  M  X@R                  U   l        M+     U R                  (       a"  U R                  R	                  5       I Sh  vN   SU l
        SU l        SSS5      ISh  vN   U R                  (       Ga  U R                  c   e[        [        R                   0 U R                  R"                  U R                  R$                  U R                  R&                  U R                  R(                  5      U l        U R                  R+                  U R,                  R.                  WU R                  U R0                  445        U R                  R+                  U R,                  R2                  U R0                  445        [4        R6                  " [8        R:                  5      (       aZ  [=        [4        U R0                  WU R                  [>        R@                  S9  [=        [4        U R0                  [>        RB                  S9  U RD                  (       d  U R                  (       a_  U RF                  R	                  5         U RF                  RI                  S5        [K        [L        RN                  " U R                  5      5        gg GN, GN GNF GN+! , ISh  vN  (       d  f       GNA= f7f)zClear pools and terminate monitors. Topology does not reopen on
demand. Any further operations will raise
:exc:`~.errors.InvalidOperation`.
NFTrI   rF   rL   )(r{   ro   r~   r   r   r   rw   itemsr   r   ry   rz   ra   rb   r.   r-   rp   rn   max_set_versionmax_election_idr   ri   r]   rq   rZ   publish_topology_closedr    re   rf   rg   r"   r#   rr   STOP_TOPOLOGYr_   rc   joinr?   r   r   )r   old_tdr   r   r   s        r>   r   Topology.close  sy    
 :::&&F--..0lln$$ 1 !% 1 1 7 7 9D#00DDFLLNmm+9;MM'*6  O
   ''--/// DLDL! :& <<+++ 3%%!!22!!11!!11!!44!D LLOOHH))))	 LLdooEEHYHYG[\]$$W]]33,,$*#00*:: ):):DVDdDd 4#3#3""((*""''* T\\!:;	 $4i  % 0 :::sq   M&L?M&=MMA!M:AM?M MM&MH"M&MMM&M#MM#M&c                    U R                   $ rP   )ro   r  s    r>   r   Topology.description  s       r   c                6    U R                   R                  5       $ )z"Pop all session ids from the pool.)r   pop_allr  s    r>   pop_all_sessionsTopology.pop_all_sessions  s    !!))++r   c                8    U R                   R                  U5      $ )z>Start or resume a server session, or raise ConfigurationError.)r   get_server_session)r   session_timeout_minutess     r>   rV  Topology.get_server_session  s    !!445LMMr   c                :    U R                   R                  U5        g rP   )r   return_server_session)r   server_sessions     r>   rZ  Topology.return_server_session  s    00@r   c                B    [         R                  " U R                  5      $ )z]A Selection object, initially including all known servers.

Hold the lock when calling this.
)r'   from_topology_descriptionro   r  s    r>   r  Topology._new_selection  s    
 2243D3DEEr   c                  #    U R                   (       a  [        S5      eU R                  (       Gd  SU l        U R                  5       I Sh  vN   U R                  (       d  U R
                  (       a  U R                  R                  5         U R                  (       a8  U R                  R                  [        ;   a  U R                  R                  5         U R                  R                  (       aG  U R                  [        U R                   S   [#        SU R$                  SS.5      5      5      I Sh  vN   U R&                  R)                  5        H  nUR                  5       I Sh  vN   M     g GN& NA N7f)zKStart monitors, or restart after a fork.

Hold the lock when calling this.
z'Cannot use AsyncMongoClient after closeTNr   rL      )ok	serviceIdmaxWireVersion)rz   r   ry   r   ra   r_   rc   r   r   r   r   r,   rk   r   r  r&   rx   r   rZ   r~   r   r   r   s     r>   r   Topology._ensure_opened  s    
 <<"#LMM|||DL&&((( 4#7#7&&++-   d&6&6&D&DH^&^!!&&(~~++**%,,Q/QT5F5FZ\]^   mm**,F++- -) )  s7   A	E8E1C&E82E434E8'E6(
E84E86E8c                   U R                   R                  U5      nUc  gUR                  R                  UR                  UR
                  5      (       a  gUR                  R                  nUR                  nS nU(       aK  [        US5      (       a:  [        UR                  [        5      (       a  UR                  R                  S5      n[        XF5      $ )NTdetailstopologyVersion)r~   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancerh  dict _is_stale_error_topology_version)r   r   err_ctxr   cur_tvro  error_tvs          r>   _is_stale_errorTopology._is_stale_error#  s    ""7+><<(()@)@'BTBTUU ##44WUI..%--.. ==,,->?/AAr   c                  #    U R                  X5      (       a  g U R                  U   nUR                  nUR                  nU R                  R
                  (       a  U(       d  UR                  (       d  g [        U[        5      (       a  UR                  (       a  g [        U[        5      (       a  g [        U[        [        45      (       Ga]  [        US5      (       a  UR                  nO5[        U[        5      (       a  SOS nUR                  R                  SU5      nU[         R"                  ;   a  U[         R$                  ;   nU R                  R
                  (       d   U R'                  [)        XS95      I S h  vN   U(       d  UR*                  S::  a  UR-                  U5      I S h  vN   UR/                  5         g UR                  (       dU  U R                  R
                  (       d   U R'                  [)        XS95      I S h  vN   UR-                  U5      I S h  vN   g g [        U[0        5      (       ao  U R                  R
                  (       d   U R'                  [)        XS95      I S h  vN   UR-                  U5      I S h  vN   UR2                  R5                  5         g g  GN2 GN N N NC N,7f)Ncodei{'  ro     )rw  r~   ro  rm  rk   r   completed_handshakerq  r   r   r   r   rp  rz  rh  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr  r&   max_wire_versionr   request_checkr   _monitorcancel_check)	r   r   rt  r   ro  rm  err_codedefaultis_shutting_downs	            r>   _handle_errorTopology._handle_error7  s    11w'''
 >>''
7C^C^e^,,1L1L
 z**1ABCC uf%% :: $.e_#E#E%4 ==,,VW=><<<#+~/M/M#M ~~33../@/VWWW#(@(@A(E ,,z222$$&00~~33../@/VWWWll:... 1 011 >>//**+<W+RSSS,,z*** OO((* 2 X 3
 X.
 T*sn   E<J>>J0?/J>.J3/AJ>J6J>$J8%AJ>6J:7J>J<!J>3J>6J>8J>:J><J>c                   #    U R                    ISh  vN   U R                  X5      I Sh  vN   SSS5      ISh  vN   g N. N N	! , ISh  vN  (       d  f       g= f7f)zHandle an application error.

May reset the server to Unknown, clear the pool, and request an
immediate check depending on the error and the context.
N)r{   r  )r   r   rt  s      r>   r@  Topology.handle_errory  s;      :::$$W666 ::6 :::sQ   A"AA"AAAA"AA"AA"AAAA"c                f    U R                   R                  5        H  nUR                  5         M     g)z3Wake all monitors. Hold the lock when calling this.N)r~   r   r  re  s     r>   r   Topology._request_check_all  s%    mm**,F  " -r   c           
     @  #    U R                   R                  5       R                  5        GHe  u  pXR                  ;  a  U R                  R                  UU U R                  U5      U R                  S9nSnU R                  (       a-  U R                  b   [        R                  " U R                  5      n[        UU R                  U5      UU R                  U R                  US9nXPR                  U'   UR                  5       I Sh  vN   M  U R                  U   R                   R"                  nX R                  U   l        XbR"                  :w  d  GM+  U R                  U   R$                  R'                  UR"                  5      I Sh  vN   GMh     [)        U R                  R                  5       5       HZ  u  pU R                   R+                  U5      (       a  M'  UR-                  5       I Sh  vN   U R                  R/                  U5        M\     g GN N N)7f)zbSync our Servers from TopologyDescription.server_descriptions.

Hold the lock while calling this.
)r   topologyr   r   N)r   r   monitortopology_id	listenersevents)ro   rw   rG  r~   rk   monitor_class_create_pool_for_monitorr_   rb   r   r   r   _create_pool_for_serverrZ   r]   r   r   is_writabler   update_is_writablerv   r  r   pop)r   r   r   r  rQ   r   was_writables          r>   r   Topology._update_servers  s    
  ,,@@BHHJKGmm+..66')!66w?&*nn	 7  ''DLL,D";;t||4D')55g># $ 1 1"oo *0g&kkm##  $}}W5AAMM57g&2>>1--055HHXXX= K@  $DMM$7$7$9:OG$$//88lln$$!!'*  ; $ Y %sD   DHHA	H5HHAHH2H3%HHHc                r    U R                   R                  XR                   R                  U R                  S9$ )N)	client_id)rk   
pool_classpool_optionsrZ   r  s     r>   r   Topology._create_pool_for_server  s3    ~~((^^00D<M<M ) 
 	
r   c                :   U R                   R                  n[        UR                  UR                  UR                  UR
                  UR                  UR                  UR                  SUR                  S9	nU R                   R                  XSU R                  S9$ )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshaker  )rk   r  r%   r  _ssl_contextr  r\   r  r  r  r  rZ   )r   r   optionsmonitor_pool_optionss       r>   r  !Topology._create_pool_for_monitor  s    ..--
  +#33"22,,(/(K(K#44OO>>))
 
 ~~((UdFWFW ) 
 	
r   c                  ^ U R                   R                  [        R                  [        R                  4;   nU(       a  SnO-U R                   R                  [        R
                  :X  a  SnOSnU R                   R                  (       a  U[        L a  U(       a  gSU-  $ SU SU S3$ [        U R                   R                  5       5      n[        U R                   R                  5       R                  5       5      nU(       d2  U(       a&  S	R                  UU R                  R                  5      $ S
U-  $ US   R                  m[        U4S jUSS  5       5      nU(       aH  Tc  SU-  $ U(       a.  [!        U5      R#                  U R$                  5      (       d  SU-  $ ['        T5      $ SR)                  S U 5       5      $ )zUFormat an error message if server selection fails.

Hold the lock when calling this.
zreplica set membersmongosesr   zNo primary available for writeszNo %s available for writeszNo z match selector ""z)No {} available for replica set name "{}"zNo %s availabler   c              3  @   >#    U  H  oR                   T:H  v   M     g 7frP   r{  ).0r   ro  s     r>   	<genexpr>*Topology._error_message.<locals>.<genexpr>  s     G;||u,;s   rL   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c              3  p   #    U  H,  oR                   (       d  M  [        UR                   5      v   M.     g 7frP   )ro  str)r  r   s     r>   r  r    s#     Xf<< 1FLL 1 1s   66)ro   r   r-   r  r  Shardedr6  r+   rv   rw   r   formatrk   rn   ro  allr  intersectionrx   r  rL  )r   r   is_replica_setserver_plural	addressesr   samero  s          @r>   r   Topology._error_message  s   
 **88//--=
 

 1M,,0E0EE&M%M**33!<7-GG]O+<XJaHHT..BBDEI4,,@@BIIKLG!FMM%77 
 -}<< AJ$$EG712;GGD=,}<<!#i.*E*EdFZFZ*[*[FHQR
 5z!xxXXXXr   c                    SnU R                   (       d  SnSU R                  R                   SU U R                  < S3$ )N zCLOSED < >)ry   	__class____name__ro   )r   msgs     r>   __repr__Topology.__repr__  s>    ||C4>>**+1SE$2C2C1FaHHr   c                    U R                   n[        [        UR                  5      5      UR                  UR
                  UR                  4$ )zDThe properties to use for AsyncMongoClient/Topology equality checks.)rk   tuplesortedrs   rn   r   srv_service_name)r   tss     r>   eq_propsTopology.eq_props  s8    ^^fRXX&')<)<bggrGZGZ[[r   c                    [        XR                  5      (       a!  U R                  5       UR                  5       :H  $ [        $ rP   )rq  r  r  NotImplemented)r   others     r>   __eq__Topology.__eq__  s/    e^^,,==?enn&666r   c                4    [        U R                  5       5      $ rP   )hashr  r  s    r>   __hash__Topology.__hash__  s    DMMO$$r   )__events_executorrz   r}   ro   rb   r]   r{   r   ry   r   r_   ra   rx   r~   r   rk   r   rZ   )r   r2   )rX   None)rX   float)NNN)r    Callable[[Selection], Selection]r   r  r   Optional[float]r   Optional[_Address]r   Optional[int]rX   list[Server])r   r  r   r  r   r  r   r  r   r  rX   list[ServerDescription])NNNN)r   r  r   r  r   r  r   r  r   Optional[list[Server]]r   r  rX   r   )NN)
r   r4   r   r  r   r  r   r  rX   r   )FF)r   r&   r   rY   r   rY   rX   r  )r  zlist[tuple[str, Any]]rX   r  )r   r4   rX   zOptional[Server])r   r4   rX   rY   )rX   r  )r   r  rX   set[_Address])rX   r  )rX   zOptional[ClusterTime])r   Optional[Mapping[str, Any]]rX   r  )   )r2  r   rX   r  )rX   r  )rX   r.   )rX   zlist[_ServerSession])rW  r  rX   r   )r[  r   rX   r  )rX   r'   )r   r4   rt  r?  rX   rY   )r   r4   rt  r?  rX   r  )r   r4   rX   r   )r   r  rX   r  )rX   r  )rX   z>tuple[tuple[_Address, ...], Optional[str], Optional[str], str])r  objectrX   rY   )rX   r   )2r  
__module____qualname____firstlineno____doc__r   r   r   r   r   r   r   r   r  r  r	  r  r   r  r  r  r   r$  r(  r   r/  r3  r8  rD  r   propertyr   rS  rV  rZ  r  r   rw  r  r@  r   r   r  r  r   r  r  r  r  __static_attributes__ r   r>   rA   rA   c   s   4fAP'(R 59&*&*#2# # #2	#
 $# $# 
#JJ#2J# J# 	J#
 $J# $J# 
!J#` 59&*8<&*2  #2	
 $  6 $ 
2 59&*8<&* 2    #2	 
 $   6  $  
 L 37&*

 
 #0	

 $
 

H !&+	H%-H% H%  $	H%
 
H%Z !&+	b-b b  $	b
 
b(89*(NP8P	PNL&6=22"=<~ ! !,NAF BB(@+D7#
(+T


,8YtI\

%r   rA   c                  6    \ rS rSrSr          SS jrSrg)r?  i  z.An error with context for SDAM error handling.c                @    Xl         X l        X0l        X@l        XPl        g rP   )ro  r  rl  r}  rm  )r   ro  r  rl  r}  rm  s         r>   r   _ErrorContext.__init__  s      
 0.#6 $r   )r}  ro  r  rm  rl  N)
ro  BaseExceptionr  r   rl  r   r}  rY   rm  zOptional[ObjectId])r  r  r  r  r  r   r  r  r   r>   r?  r?    s:    8%% % 	%
 "% '%r   r?  c                @    U b  Uc  gU S   US   :w  a  gU S   US   :  $ )z9Return True if the error's topologyVersion is <= current.F	processIdcounterr  )
current_tvrv  s     r>   rs  rs  ,  s<     X-+(;"77i HY$777r   c                n    U R                   UR                   p2Ub  Uc  gUS   US   :w  a  gUS   US   :  $ )z4Return True if the new topologyVersion is < current.Fr  r  )rn  )
current_sdnew_sdr  new_tvs       r>   r   r   7  sL    #44f6M6MV^+&"55i 6)#444r   c                f    U(       d  U $ U  Vs/ s H  o"U;  d  M
  UPM     nnU=(       d    U $ s  snf )zBFilter out deprioritized servers from a list of server candidates.r  )
candidatesr   r   filtereds       r>   r   r   A  s:     !%/WZ6AV3VZHW !z! Xs   	..)r9   z"weakref.ReferenceType[queue.Queue]rX   rY   )r  r  rv  r  rX   rY   )r  r&   r  r&   rX   rY   rP   )r  r  r   r  rX   r  )Zr  
__future__r   rf   r   r7   r   r   r   r   r   pathlibr   typingr   r   r   r   r	   r
   pymongor   r   r   pymongo.asynchronousr   #pymongo.asynchronous.client_sessionr   r   pymongo.asynchronous.monitorr   pymongo.asynchronous.poolr   pymongo.asynchronous.serverr   pymongo.errorsr   r   r   r   r   r   r   r   pymongo.hellor   pymongo.lockr   r   r   pymongo.loggerr    r!   r"   r#   r$   pymongo.pool_optionsr%   pymongo.server_descriptionr&   pymongo.server_selectorsr'   r(   r)   r*   r+   pymongo.topology_descriptionr,   r-   r.   r/   r0   bsonr1   pymongo.asynchronous.settingsr2   pymongo.typingsr3   r4   _IS_SYNCr  __file__parentr   r?   rA   r?  rs  r   r   r  r   r>   <module>r     s   C "  	   
     H H 1 1 2 R 3 * .	 	 	   : :  - 8   >54>(()"t% t%n% %$8+87R8	85 OS
"
"5K
"
"r   