
    nh                    R   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZ ddlmZmZmZmZmZmZ ddlmZmZmZmZ ddlmZmZ ddlmZmZ dd	l m!Z! dd
l"m#Z# ddl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z?m@Z@mAZAmBZBmCZC ddlDmEZEmFZFmGZGmHZHmIZI erddlJmKZK ddlLmMZM ddlNmOZOmPZP dZQ eR eeS      j                        ZUddZV G d d      ZW G d d      ZX	 	 	 	 	 	 d dZYd!dZZ	 d"	 	 	 	 	 d#dZ[y)$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)MonitorBase
SrvMonitor)Pool)Server)	ConnectionFailureInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailurePyMongoErrorServerSelectionTimeoutErrorWaitQueueTimeoutError
WriteError)Hello)_async_cond_wait_async_create_condition_async_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                     |        }|sy	 	 |j                         }|\  }} ||  # t        j                  $ r Y yw xY w)NFT)
get_nowaitqueueEmpty)	queue_refqeventfnargss        /var/www/html/SchoolMeal/SchoolMeal/pds_admin_SchoolMeal/Backend/venv/lib/python3.12/site-packages/pymongo/asynchronous/topology.pyprocess_events_queuerA   W   sV    A
	LLNE HBI  {{ 	
 	s   ( >>c                  B   e Zd ZdZd/dZd0dZd1dZ	 	 	 d2	 	 	 	 	 	 	 	 	 	 	 d3dZ	 	 	 	 	 	 	 	 	 	 	 	 d4dZ	 	 	 	 d5	 	 	 	 	 	 	 	 	 	 	 	 	 d6dZ		 	 	 	 d5	 	 	 	 	 	 	 	 	 	 	 	 	 d6d	Z
	 	 d7	 	 	 	 	 	 	 	 	 d8d
Z	 	 d9	 	 	 	 	 	 	 d:dZ	 	 d9	 	 	 	 	 	 	 d:dZd;dZd;dZd<dZd=dZd>dZ	 	 	 	 d?dZd@dZd@dZdAdZdBdZdBdZdCdDdZdEdZd0dZd0dZedFd       ZdGdZdHdZ dIdZ!dJd Z"d0d!Z#dKd"Z$dLd#Z%dLd$Z&d0d%Z'd0d&Z(dMd'Z)dMd(Z*dNd)Z+d0d*Z,dOd+Z-dPd,Z.dQd-Z/dRd.Z0y)STopologyz*Monitor a topology of one or more servers.c           	     	   |j                   | _         |j                  j                  | _        | j                  d uxr | j                  j                  | _        | j                  d uxr | j                  j                  | _        d | _        d | _	        | j
                  s| j                  rt        j                  d      | _        t        j                  t        j                        r*t!        t        t"        j$                  | j                          | j                  rJ| j                  J | j                  j'                  | j                  j(                  | j                   ff       || _        t-        |j/                         |j1                         |j2                  d d |      }|| _        t-        t6        j8                  i d d d | j*                        }| j                  rV| j                  J | j                  j'                  | j                  j:                  || j4                  | j                   ff       t        j                  t        j                        r6t!        t        t"        j<                  | j                   || j4                         |j>                  D ]  }| j
                  rK| j                  J | j                  j'                  | j                  j@                  || j                   ff       t        j                  t        j                        s~t!        t        t"        jB                  | j                   |d   |d           tE        |jG                               | _$        d| _%        d| _&        tO               | _(        tS        | jP                  tT        r| j*                  jV                  nd       | _,        i | _-        d | _.        d | _/        ta               | _1        | j
                  s| j                  r| j                  J dfd	}te        jf                  th        jj                  th        jl                  |d
      }to        jp                  | j                  |jr                        || _	        |ju                          d | _;        | j*                  jx                  1| j*                  jz                  st}        | | j*                        | _;        g | _?        y )Nd   )maxsizemessage
topologyIdrH   rI   previousDescriptionnewDescriptionr      )rH   rI   
serverHost
serverPortFc                 "   K   t               S wN)rA   )weaks   r@   targetz!Topology.__init__.<locals>.target   s     +D11s   pymongo_events_thread)intervalmin_intervalrS   name)returnbool)@_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr9   Queuer"   isEnabledForloggingDEBUGr$   r%   START_TOPOLOGYputpublish_topology_opened	_settingsr0   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!   _lockr    _IS_SYNCcondition_class
_condition_servers_pid_max_cluster_timer   _session_poolr   AsyncPeriodicExecutorr   EVENTS_QUEUE_FREQUENCYMIN_HEARTBEAT_INTERVALweakrefrefcloseopen_srv_monitorfqdnload_balancedr   _monitor_tasks)selftopology_settingstopology_description
initial_tdseedrS   executorrR   s          @r@   __init__zTopology.__init__k   s   -::+99JJ#d:at?a?a??$6_4??;_;_ &*4#3#3 ;;s3DL$$W]]3*99,, <<+++LLdooEEHYHYG[\]*2//1557.. 
 1(!!2tT4

 <<+++LLOOHH!2!2D4E4EF $$W]]3*::,,$.#00 &++ 	D##||///  $//"G"G$PTPaPaIb!cd((7 .;;#00#Aw#Aw	  $$8$L$L$NO')
1JJ(66
 13#'	8</14#3#3<<+++2 )>>66#::,	H ;;t||X^^<D%-D"MMO >>*4>>3O3O *4 @D 24    c                  K   t        j                         }| j                  || _        n|| j                  k7  r|| _        t        j                  dd dk\  r
dt
        fi}nddi}t        j                  	 di | | j                  4 d{    | j                  j                         D ]  }|j                          d{     | j                  j                          ddd      d{    | j                  4 d{    | j                          d{    ddd      d{    y7 7 p7 F# 1 d{  7  sw Y   VxY w7 H7 27 $# 1 d{  7  sw Y   yxY ww)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://dochub.mongodb.org/core/pymongo-fork-deadlock)osgetpidr   sysversion_info_pymongo_dirwarningswarnr{   r   valuesr   r   reset_ensure_opened)r   pidkwargsservers       r@   r   zTopology.open   sO     iik99DIDIIDI#w..@&*MMH 	 zz + +"mm224 )F ,,.(() ""((*+ + :: 	( 	(%%'''	( 	( 	(+ )+ + + +	('	( 	( 	( 	(s   B	E%D/E%1D5 D1 D5!E%,D3-E%E
E%EEEE%)E*E%1D53E%5E;D><EE%EE%E"EE"E%c                ^    t        j                         }|| j                  j                  S |S rQ   )r   	remainingrk   server_selection_timeout)r   timeouts     r@   get_server_selection_timeoutz%Topology.get_server_selection_timeout   s(    //#?>>:::r   Nc           
       K   || j                         }n|}t        s$| j                  r| j                          d{    | j                  4 d{    | j                  |||||       d{   }|D cg c]+  }t        t        | j                  |j                              - c}cddd      d{    S 7 ~7 k7 Pc c}w 7 # 1 d{  7  sw Y   yxY ww)a  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|   r   cleanup_monitorsr{   _select_servers_loopr
   r   get_server_by_addressaddress)	r   selector	operationr   r   operation_idserver_timeoutrw   sds	            r@   select_serverszTopology.select_servers  s     . $+!>>@N5N D//''))):: 	 	(,(A(A.)\7) #
 PcIKVT77

CD	 	 	 *	#	 	 	 	s{   ;CB<CB>CC	/C 0C	80C(C	*C6C7C>C C	C	C	CCCCc                  K   t        j                         }||z   }d}t        j                  t        j
                        rLt        t        t        j                  |||| j                  | j                  j                  j                         | j                  j                  ||| j                  j                        }	|	s|dk(  s||kD  rt        j                  t        j
                        r\t        t        t        j                   |||| j                  | j                  j                  j                  | j#                  |             t%        | j#                  |       d| d| j                        |spt        t        t        j&                  |||| j                  | j                  j                  j                  t)        d|t        j                         z
  z        	       d
}| j+                          d{    | j-                          t/        | j0                  t2        j4                         d{    | j                  j7                          t        j                         }| j                  j                  ||| j                  j                        }	|	s| j                  j7                          |	S 7 7 w)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: i  )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   r~   r   r   check_compatible)
r   r   r   r   r   r   nowend_timelogged_waitingrw   s
             r@   r   zTopology._select_servers_loop.  sV     nn=#00?(5==!#($($4$4))<<II #//>>gt~~/M/M ? 
 &!|sX~+88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>>;K0K(L$M	 "&%%'''##% #4??F4Q4QRRR..0.."C"&"3"3"B"B'4>>3Q3Q #C #S &Z 	**,"" ( Ss+   G:K<J==;K8J?9A&K!K?Kc                  K   | j                  |||||       d {   }t        ||      }t        |      dk(  r|d   S t        j                  |d      \  }}	|j
                  j                  |	j
                  j                  k  r|S |	S 7 mw)NrM   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
r   r   r   r   r   deprioritized_serversr   serversserver1server2s
             r@   _select_serverzTopology._select_serverz  s      ++i!97L
 
 "'+@Aw<11:!==!4<<''7<<+G+GGNN
s   BB	A.Bc                  K   | j                  ||||||       d{   }t        j                         r)t        j                  |j                  j
                         t        j                  t        j                        r|t        t        t        j                  |||| j                  | j                  j                  j                  |j                  j                  d   |j                  j                  d   	       |S 7 w)zALike select_servers, but choose a random server if several match.r   Nr   rM   )rH   r   r   r   r   r   rN   rO   )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_serverz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                R   K   | j                  t        ||||       d{   S 7 w)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_addressz!Topology.select_server_by_address  s9     2 ''$% ( 
 
 	
 
s   '%'c                .  K   | j                   }|j                  |j                     }t        ||      ryt	        | j                   |      }|j
                  s)|j                  rf|j                  t        j                  k(  rI| j                  j                  |j                        }|r"|j                  j                          d{    ||k(  }| j                  rY|sW| j                  J | j                  j!                  | j"                  j$                  |||j                  | j&                  ff       || _         | j)                          d{    | j*                  rX|sV| j                  J | j                  j!                  | j"                  j,                  || j                   | j&                  ff       t/        j0                  t2        j4                        r8|s6t7        t.        t8        j:                  | j&                  || j                          | j<                  r|j                  t        j>                  k(  ri| j                   j                  t@        vrM| j<                  jC                          d{    tD        s%| jF                  jI                  | j<                         |rK| j                  j                  |j                        }|r$|j                  jK                  |       d{    | jL                  jO                          y7 G7 7 7 'w)ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        NrJ   )interrupt_connections)(ro   _server_descriptionsr   _is_stale_server_descriptionr2   is_readableis_server_type_knowntopology_typer/   Singler   getr   readyr_   rb   ri   r]   "publish_server_description_changedrZ   _update_serversra   rq   r"   re   rf   rg   r$   r%   rr   r   rp   r.   r   r|   r   appendr   r~   
notify_all)	r   server_description
reset_poolr   td_oldsd_oldnew_tdr   suppress_events	            r@   _process_changezTopology._process_change  s     "",,-?-G-GH'0BC-d.?.?AST))338L8LP]PdPd8d]]&&'9'A'ABFkk'')))#55<<+++LLOOFF/1C1K1KTM^M^_ #""$$$N<<+++LLOOHHT..0A0AB $$W]]3N*::,,$*#00   M$9$99!!//7MM##))+++##**4+<+<= ]]&&'9'A'ABFkk''>S'TTT 	""$e * 	%4 , UsK   CLLBLLD%L3L4A7L+L, LLLLc                $  K   | j                   4 d{    | j                  r@| j                  j                  |j                        r| j                  |||       d{    ddd      d{    y7 a7 7 	# 1 d{  7  sw Y   yxY ww)z>Process a new ServerDescription after an hello call completes.N)r{   ry   ro   
has_serverr   r   )r   r   r   r   s       r@   	on_changezTopology.on_change  s      :: 
	b 
	b || 1 1 < <=O=W=W X**+=zK`aaa
	b 
	b 
	b b
	b 
	b 
	b 
	bsW   BA5BAA;A7 A;$B/A90B7A;9B;BBB	Bc                ,  K   | j                   }|j                  t        vryt        | j                   |      | _         | j	                          d{    | j
                  rV| j                  J | j                  j                  | j                  j                  || j                   | j                  ff       t        j                  t        j                        r7t        t        t         j"                  | j                  || j                          yy7 w)z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        NrJ   )ro   r   r.   r1   r   ra   rb   ri   r]   rq   rZ   r"   re   rf   rg   r$   r%   rr   )r   seedlistr   s      r@   _process_srv_updatezTopology._process_srv_update1  s      ""'==EdFWFWYab""$$$<<+++LLOOHHT..0A0AB $$W]]3*::,,$*#00 4 	%s   ADDCDc                   K   | j                   4 d{    | j                  r| j                  |       d{    ddd      d{    y7 :7 7 	# 1 d{  7  sw Y   yxY ww)z?Process a new list of nodes obtained from scanning SRV records.N)r{   ry   r   )r   r   s     r@   on_srv_updatezTopology.on_srv_updateM  s]      :: 	9 	9||..x888	9 	9 	98	9 	9 	9 	9sS   A)AA)!AAAA)A	A)AA)A&AA&"A)c                8    | j                   j                  |      S )aJ  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   zTopology.get_server_by_addressT  s     }}  ))r   c                    || j                   v S rQ   )r   r  s     r@   r   zTopology.has_server^  s    $--''r   c                N  K   | j                   4 d{    | j                  j                  }|t        j                  k7  r	 ddd      d{    yt        | j                               d   j                  cddd      d{    S 7 v7 >7 	# 1 d{  7  sw Y   yxY ww)z!Return primary's address or None.Nr   )r{   ro   r   r/   ReplicaSetWithPrimaryr-   _new_selectionr   )r   r   s     r@   get_primaryzTopology.get_primarya  s      :: 	N 	N --;;M C CC	N 	N 	N
 ,D,?,?,AB1EMM	N 	N 	N 	N 	N 	N 	N 	Nsb   B%B
B%+BB%BB%%B8B%BB%B%B%B"BB"B%c                  K   | j                   4 d{    | j                  j                  }|t        j                  t        j
                  fvrt               cddd      d{    S t         || j                                     D ch c]  }|j                   c}cddd      d{    S 7 7 Oc c}w 7 # 1 d{  7  sw Y   yxY ww)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_membersz!Topology._get_replica_set_membersk  s     
 :: 	P 	P --;;M3311%  u	P 	P 	P *.ht7J7J7L.M)NO2BJJO	P 	P 	P 	P P	P 	P 	P 	Psu   CB3CAB>C%B5&C+!B>B7B>!C-B<.C5C7B><C>CCCCc                H   K   | j                  t               d{   S 7 w)z"Return set of secondary addresses.N)r  r,   r   s    r@   get_secondarieszTopology.get_secondariesz  s     223LMMMM   " "c                H   K   | j                  t               d{   S 7 w)z Return set of arbiter addresses.N)r  r+   r  s    r@   get_arbiterszTopology.get_arbiters~  s     223JKKKKr  c                    | j                   S )z1Return a document, the highest seen $clusterTime.r   r  s    r@   max_cluster_timezTopology.max_cluster_time  s    %%%r   c                \    |r*| j                   r|d   | j                   d   kD  r|| _         y y y )NclusterTimer  r   cluster_times     r@   _receive_cluster_time_no_lockz&Topology._receive_cluster_time_no_lock  s=      **.1G1G1VV)5& W	 r   c                   K   | j                   4 d {    | j                  |       d d d       d {    y 7 &7 # 1 d {  7  sw Y   y xY wwrQ   )r{   r  r  s     r@   receive_cluster_timezTopology.receive_cluster_time  sJ     :: 	= 	=..|<	= 	= 	= 	= 	= 	= 	=s<   A:A>A<AAAAAAc                   K   | j                   4 d{    | j                          t        | j                  |       d{    ddd      d{    y7 C7 7 	# 1 d{  7  sw Y   yxY ww)z=Wake all monitors, wait for at least one to check its server.N)r{   r   r   r~   )r   	wait_times     r@   request_check_allzTopology.request_check_all  s`     :: 	? 	?##%"4??I>>>	? 	? 	?>	? 	? 	? 	?sV   A2AA2*AAAA2AA2AA2A/#A&$A/+A2c                    | j                   j                  t        j                  k(  r| j                   j                  S | j                   j
                  S )z~Return 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_serverszTopology.data_bearing_servers  sB    
 **m.B.BB$$222  111r   c           	     R  K   g }| j                   4 d {    | j                         D ]P  }| j                  |j                     }|j	                  ||j
                  j                  j                         f       R d d d       d {    |D ])  \  }}	 |j
                  j                  |       d {    + y 7 7 5# 1 d {  7  sw Y   ExY w7  # t        $ rD}t        |d|dd       }| j                  |j                  j                  |       d {  7    d }~ww xY ww)Nr   F)r{   r%  r   r   r   r   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )r   r   r   r   
generationexcctxs          r@   update_poolzTopology.update_pool  s    :: 	H 	H//1 Hrzz2(C(C(EFGH	H 	H #* 	FJkk66zBBB		H 	H 	H 	H 	H C #CJtD''(:(:(B(BCHHHs   D'B<D'A$C =D'B>	D'C4C5C9D'>D' CC	CD'C	D$ 8DDDD$$D'c                T  K   | j                   4 d{    | j                  }| j                  j                         D ]F  }|j	                          d{    t
        r"| j                  j                  |j                         H | j                  j                         | _        | j                  j                         j                         D ](  \  }}|| j                  v s|| j                  |   _        * | j                  rM| j                  j	                          d{    t
        s%| j                  j                  | j                         d| _        d| _        ddd      d{    | j                   r| j"                  J t%        t&        j(                  i | j                  j*                  | j                  j,                  | j                  j.                  | j                  j0                        | _        | j"                  j3                  | j4                  j6                  | j                  | j8                  ff       | j"                  j3                  | j4                  j:                  | j8                  ff       t=        j>                  t@        jB                        r`tE        t<        tF        jH                  | j8                  | j                         tE        t<        tF        jJ                  | j8                         | jL                  s| j                   rf| jN                  j	                          | jN                  jQ                  d       d{    tS        tU        jV                  | j"                               yy7 q7 37 h7 "# 1 d{  7  sw Y   3xY w7 Pw)zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        NFTrJ   rG   rM   ),r{   ro   r   r   r   r|   r   r   _monitorr   rw   itemsr   r   ry   rz   ra   rb   r0   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   joinrA   r   r   )r   old_tdr   r   r   s        r@   r   zTopology.close  s    
 :: 	  	 &&F--..0 @lln$$''..v?@ !% 1 1 7 7 9D#00DDFLLN <dmm+9;DMM'*6<
   ''--///''..t/@/@A DLDL)	  	 . <<+++ 3%%!!22!!11!!11!!44!D LLOOHH))))	 LLdooEEHYHYG[\]$$W]]3*::,,$*#00 &8&F&FSWSdSd 4#3#3""((*((--a000 T\\!:;	 $4q	  % 0	  	  	  	 v 1s   N(NN(=NN
N BN#?N"N
#=N N(+N,G)N(N&/N(N
NN(N#NN#	N(c                    | j                   S rQ   )ro   r  s    r@   r   zTopology.description  s       r   c                6    | j                   j                         S )z"Pop all session ids from the pool.)r   pop_allr  s    r@   pop_all_sessionszTopology.pop_all_sessions   s    !!))++r   c                8    | j                   j                  |      S )z>Start or resume a server session, or raise ConfigurationError.)r   get_server_session)r   session_timeout_minutess     r@   r>  zTopology.get_server_session  s    !!445LMMr   c                :    | j                   j                  |       y rQ   )r   return_server_session)r   server_sessions     r@   rA  zTopology.return_server_session  s    00@r   c                @    t        j                  | j                        S )zmA Selection object, initially including all known servers.

        Hold the lock when calling this.
        )r)   from_topology_descriptionro   r  s    r@   r  zTopology._new_selection  s    
 2243D3DEEr   c                  K   | j                   rt        d      | j                  sd| _        | j                          d{    | j                  s| j
                  r| j                  j                          | j                  r6| j                  j                  t        v r| j                  j                          | j                  j                  rG| j                  t        | j                   d   t#        d| j$                  dd                   d{    | j&                  j)                         D ]  }|j                          d{     y7 7 ?7 w)z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z'Cannot use AsyncMongoClient after closeTNr   rM      )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   zTopology._ensure_opened  s     
 <<"#LMM||DL&&((( 4#7#7&&++-   d&6&6&D&DH^&^!!&&(~~++**%,,Q/QT5F5FZ\]^   mm**, 	 F++-	 ) )  s6   >E ECEE4EEEEEc                   | j                   j                  |      }|y|j                  j                  |j                  |j
                        ry|j                  j                  }|j                  }d }|rAt        |d      r5t        |j                  t              r|j                  j                  d      }t        ||      S )NTdetailstopologyVersion)r   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancerL  dict _is_stale_error_topology_version)r   r   err_ctxr   cur_tvrS  error_tvs          r@   _is_stale_errorzTopology._is_stale_error3  s    ""7+><<(()@)@'BTBTU ##44WUI.%--. ==,,->?/AAr   c                  K   | j                  ||      ry | j                  |   }|j                  }|j                  }| j                  j
                  r|s|j                  sy t        |t              r|j                  ry t        |t              ry t        |t        t        f      rCt        |d      r|j                  }n0t        |t              rdnd }|j                  j                  d|      }|t         j"                  v r|t         j$                  v }| j                  j
                  s$| j'                  t)        ||             d {    |s|j*                  dk  r|j-                  |       d {    |j/                          y |j                  sT| j                  j
                  s$| j'                  t)        ||             d {    |j-                  |       d {    y y t        |t0              rt        |t2              ry | j                  j
                  s$| j'                  t)        ||             d {    |j-                  |       d {    |j4                  j7                          y y 7 17 
7 7 7 C7 ,w)Ncodei{'  rS     )r[  r   rS  rQ  rk   r   completed_handshakerU  r   r   r   r   rT  r]  rL  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r(   max_wire_versionr   request_checkr   r   r1  cancel_check)	r   r   rX  r   rS  rQ  err_codedefaultis_shutting_downs	            r@   _handle_errorzTopology._handle_errorG  s    1w'''
 >>''
7C^C^e^,1L1L
 z*1ABC uf% :: $.e_#E%4 ==,,VW=><<<#+~/M/M#M ~~33../@PU/VWWW#(@(@A(E ,,z222$$&00~~33../@PU/VWWWll:... 1 01%!67 >>//**+<WE+RSSS,,z*** OO((* 2 X 3
 X. T*sn   EJ	I:
)J3I=4AJ
J J#J$AJ JJJ!J=J JJJJc                   K   | j                   4 d{    | j                  ||       d{    ddd      d{    y7 /7 7 	# 1 d{  7  sw Y   yxY ww)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{   ri  )r   r   rX  s      r@   r+  zTopology.handle_error  sX      :: 	7 	7$$Wg666	7 	7 	76	7 	7 	7 	7sQ   AAAA	AA	AAAA	A	AAAAc                b    | j                   j                         D ]  }|j                           y)z3Wake all monitors. Hold the lock when calling this.N)r   r   rd  rJ  s     r@   r   zTopology._request_check_all  s*    mm**, 	#F  "	#r   c           	       K   | j                   j                         j                         D ]c  \  }}|| j                  vr| j                  j                  || | j                  |      | j                        }d}| j                  r+| j                  t        j                  | j                        }t        || j                  |      || j                  | j                  |      }|| j                  |<   |j                          d{    | j                  |   j                   j"                  }|| j                  |   _        ||j"                  k7  s*| j                  |   j$                  j'                  |j"                         d{    f t)        | j                  j                               D ]  \  }}| j                   j+                  |      r"|j-                          d{    t.        s%| j0                  j3                  |j4                         | j                  j7                  |        y7 17 7 Rw)zrSync 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   r2  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   r|   r   r   r1  pop)r   r   r   rn  rR   r   was_writables          r@   r   zTopology._update_servers  s    
  ,,@@BHHJ 	YKGRdmm+..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2>>1--055HHXXX=	Y@  $DMM$7$7$9: 	+OGV$$//8lln$$''..v?!!'*	+ $ Y %sE   DH?H8AH?5H?
H;AH?H?*H=+AH?;H?=H?c                z    | j                   j                  || j                   j                  | j                        S )N)	client_id)rk   
pool_classpool_optionsrZ   r  s     r@   rt  z Topology._create_pool_for_server  s5    ~~((T^^00D<M<M ) 
 	
r   c                H   | j                   j                  }t        |j                  |j                  |j                  |j
                  |j                  |j                  |j                  d|j                  	      }| j                   j                  ||d| j                        S )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshakerz  )rk   r|  r'   r~  _ssl_contextr  r\   r  r  r  r{  rZ   )r   r   optionsmonitor_pool_optionss       r@   rs  z!Topology._create_pool_for_monitor  s    ..--
  +#33"22,,(/(K(K#44OO>>))
 
 ~~(()UdFWFW ) 
 	
r   c                0   | j                   j                  t        j                  t        j                  fv }|rd}n,| j                   j                  t        j
                  k(  rd}nd}| j                   j                  r|t        u r|ryd|z  S d| d| dS t        | j                   j                               }t        | j                   j                         j                               }|s-|r&d	j                  || j                  j                        S d
|z  S |d   j                  t        fd|dd D              }|r=d|z  S |r)t!        |      j#                  | j$                        sd|z  S t'              S dj)                  d |D              S )zeFormat 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  <   K   | ]  }|j                   k(    y wrQ   r^  ).0r   rS  s     r@   	<genexpr>z*Topology._error_message.<locals>.<genexpr>	  s     Gv||u,Gs   rM   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c              3  `   K   | ]&  }|j                   st        |j                          ( y wrQ   )rS  str)r  r   s     r@   r  z*Topology._error_message.<locals>.<genexpr>  s     Xf6<<FLL 1Xs   ..)ro   r   r/   r  r  Shardedr#  r-   rv   rw   r   formatrk   rn   rS  allr  intersectionrx   r  r7  )r   r   is_replica_setserver_plural	addressesr   samerS  s          @r@   r   z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                4  K   g }	 | j                   r6|j                  | j                   j                                | j                   r6t	        j
                  |D cg c]  }|j                          c}ddi d {    y # t        $ r Y Ew xY wc c}w 7 w)Nreturn_exceptionsT)r   r   rw  
IndexErrorasynciogatherr7  )r   tasksts      r@   r   zTopology.cleanup_monitors  s     	%%T004467 %% nn7Aqvvx7P4PPP  		7PsA   BAB BB2
B<B=B	BBB	Bc                t    d}| j                   sd}d| j                  j                   d| | j                  dS )N zCLOSED < >)ry   	__class____name__ro   )r   msgs     r@   __repr__zTopology.__repr__#  s>    ||C4>>**+1SE$2C2C1FaHHr   c                    | j                   }t        t        |j                              |j                  |j
                  |j                  fS )zDThe properties to use for AsyncMongoClient/Topology equality checks.)rk   tuplesortedrs   rn   r   srv_service_name)r   tss     r@   eq_propszTopology.eq_props)  s8    ^^fRXX&')<)<bggrGZGZ[[r   c                |    t        || j                        r!| j                         |j                         k(  S t        S rQ   )rU  r  r  NotImplemented)r   others     r@   __eq__zTopology.__eq__.  s.    eT^^,==?enn&666r   c                4    t        | j                               S rQ   )hashr  r  s    r@   __hash__zTopology.__hash__3  s    DMMO$$r   )r   r4   )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   r6   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   r6   rX   zOptional[Server])r   r6   rX   rY   )rX   r  )r   r  rX   set[_Address])rX   r  )rX   zOptional[ClusterTime])r  Optional[Mapping[str, Any]]rX   r  )   )r   r   rX   r  )rX   r  )rX   r0   )rX   zlist[_ServerSession])r?  r  rX   r   )rB  r   rX   r  )rX   r)   )r   r6   rX  r*  rX   rY   )r   r6   rX  r*  rX   r  )r   r6   rX   r   )r   r  rX   r  )rX   r  )rX   z>tuple[tuple[_Address, ...], Optional[str], Optional[str], str])r  objectrX   rY   )rX   r   )1r  
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r  r   r   r	  r  r  r  r  r  r  r!  r%  r/  r   propertyr   r<  r>  rA  r  r   r[  ri  r+  r   r   rt  rs  r   r   r  r  r  r   r   r@   rC   rC   h   s   4j4X%(N 59&*&*'2' ' #2	'
 $' $' 
'RJ#2J# J# 	J#
 $J# $J# 
!J#` 59&*8<&*2  #2	
 $  6 $ 
2 59&*8<&* 2    #2	 
 $   6  $  
 L 37&*

 
 #0	

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


,8YtQI\

%r   rC   c                  ,    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddZy)r*  z.An error with context for SDAM error handling.c                J    || _         || _        || _        || _        || _        y rQ   )rS  rc  rP  r`  rQ  )r   rS  rc  rP  r`  rQ  s         r@   r   z_ErrorContext.__init__:  s*     
 0.#6 $r   N)
rS  BaseExceptionrc  r   rP  r   r`  rY   rQ  zOptional[ObjectId])r  r  r  r  r   r  r   r@   r*  r*  7  s:    8%% % 	%
 "% '%r   r*  c                :    | |y| d   |d   k7  ry| d   |d   k\  S )z9Return True if the error's topologyVersion is <= current.F	processIdcounterr  )
current_tvrZ  s     r@   rW  rW  I  s<     X-+(;"77i HY$777r   c                j    | j                   |j                   }}||y|d   |d   k7  ry|d   |d   kD  S )z4Return True if the new topologyVersion is < current.Fr  r  )rR  )
current_sdnew_sdr  new_tvs       r@   r   r   T  sN    #44f6M6MJV^+&"55i 6)#444r   c                H    |s| S | D cg c]	  }||vs| }}|xs | S c c}w )zBFilter out deprioritized servers from a list of server candidates.r  )
candidatesr   r   filtereds       r@   r   r   ^  s;     !%/W66AV3VWHW !z! Xs   	)r;   z"weakref.ReferenceType[queue.Queue]rX   rY   )r  r  rZ  r  rX   rY   )r  r(   r  r(   rX   rY   rQ   )r  r  r   r  rX   r  )\r  
__future__r   r  rf   r   r9   r   r   r   r   r   pathlibr   typingr   r   r   r   r	   r
   pymongor   r   r   r   #pymongo.asynchronous.client_sessionr   r   pymongo.asynchronous.monitorr   r   pymongo.asynchronous.poolr   pymongo.asynchronous.serverr   pymongo.errorsr   r   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/   r0   r1   r2   bsonr3   pymongo.asynchronous.settingsr4   pymongo.typingsr5   r6   r|   r  __file__parentr   rA   rC   r*  rW  r   r   r  r   r@   <module>r     s   C "   	   
     H H D D R @ * .
 
 
   
  - 8   >54>(()"L% L%^% %$8+87R8	85 OS
"
"5K
"
"r   