
    _i                    L   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          jT                  ZUd-dZV G d d          ZW G d d          ZXd.d#ZYd/d'ZZ	 d0d1d,Z[dS )2z<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_AddressF	queue_ref"weakref.ReferenceType[queue.Queue]returnboolc                     |             }|sdS 	 	 |                                 }|\  }} ||  n# t          j        $ r Y nw xY w6dS )NFT)
get_nowaitqueueEmpty)r7   qeventfnargss        @D:\Nbitz\venv\Lib\site-packages\pymongo/asynchronous/topology.pyprocess_events_queuerD   W   sy    	A u	LLNNE HBBIII	 { 	 	 	E	 4s   0 AAc                     e Zd ZdZdadZdbdZdcd	Z	 	 	 dddedZdfdZ	 	 	 	 dgdhdZ		 	 	 	 dgdhdZ
	 	 didjd Z	 	 dkdld'Z	 	 dkdld(Zdmd+Zdmd,Zdnd.Zdod/Zdpd0Zdqd2Zdrd3Zdrd4Zdsd6Zdtd9Zdtd:Zdudvd>Zdwd?Zdbd@ZdbdAZedxdC            ZdydEZdzdHZ d{dJZ!d|dLZ"dbdMZ#d}dPZ$d~dQZ%d~dRZ&dbdSZ'dbdTZ(ddVZ)ddWZ*ddXZ+dbdYZ,ddZZ-dd\Z.dd_Z/dd`Z0d
S )Topologyz*Monitor a topology of one or more servers.topology_settingsr4   c           	     2   |j         | _         |j        j        | _        | j        d uo| j        j        | _        | j        d uo| j        j        | _        d | _        d | _	        | j        s| j        rt          j        d          | _        t          j        t          j                  r&t!          t          t"          j        | j                    | j        r5| j        J | j                            | j        j        | j         ff           || _        t-          |                                |                                |j        d d |          }|| _        t-          t6          j        i d d d | j                  }| j        r<| j        J | j                            | j        j        || j        | j         ff           t          j        t          j                  rGt!          t          t"          j        | j         t?          |          t?          | j                             |j         D ]}| j        r6| j        J | j                            | j        j!        || j         ff           t          j        t          j                  r4t!          t          t"          j"        | j         |d         |d                    tG          |$                                          | _%        d| _&        d| _'        tQ                      | _)        tU          | j)        tV          r| j        j,        nd           | _-        i | _.        d | _/        d | _0        tc                      | _2        | j        s| j        ru| j        J dfd}tg          j4        tj          j6        tj          j7        |d          }tq          j9        | j        |j:                  || _	        |;                                 d | _<        | j        j=        &| j        j>        st          | | j                  | _<        g | _@        d S )Nd   )maxsizemessage
topologyIdrL   rM   previousDescriptionnewDescriptionr      )rL   rM   
serverHost
serverPortFr9   r:   c                 &   K   t                     S N)rD   )weaks   rC   targetz!Topology.__init__.<locals>.target   s      +D111    pymongo_events_thread)intervalmin_intervalrW   name)r9   r:   )A_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr=   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repr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)selfrG   topology_description
initial_tdseedrW   executorrV   s          @rC   __init__zTopology.__init__k   s   -:+9J#d:at?a?$6_4?;_ &* 	44#3 	4 ;s333DL$W]33 	*9,     	^<+++LdoEHYG[\]]]*2//115577. 
  
 1(!2tT4
 

  	<+++LOH!2D4EF   $W]33 	*:,$($4$4#D$566    &+ 	 	D# e|///  $/"G$PTPaIb!cddd(77  .;#0#Aw#Aw     $$8$L$L$N$NOO'))
1J(L66
 
 13#'	8</11 	4#3 	<+++2 2 2 2 2 2 )>6#:,	  H ;t|X^<<D%-D"MMOOO >*4>3O* *4 @ @D 24rX   r9   Nonec                |  K   t          j                    }| j        || _        n|| j        k    r|| _        t          j        dd         dk    rdt
          fi}nddi}t          j        	 di | | j        4 d{V  | j	        
                                D ]}|                                 d{V  | j                                         ddd          d{V  n# 1 d{V swxY w Y   | j        4 d{V  |                                  d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )	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   AsyncMongoClient 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)r   )osgetpidr   sysversion_info_pymongo_dirwarningswarnr   r   valuesr   r   reset_ensure_opened)r   pidkwargsservers       rC   r   zTopology.open   s      ikk9DIIDIDI#w...@&*MH  	   z + + + + + + + +"m2244 ) )F ,,..(((((((( "((***+ + + + + + + + + + + + + + + + + + + + + + + + + + + : 	( 	( 	( 	( 	( 	( 	( 	(%%'''''''''	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(s%   =AC
C),C)=D++
D58D5floatc                H    t          j                    }|| j        j        S |S rU   )r   	remainingrn   server_selection_timeout)r   timeouts     rC   get_server_selection_timeoutz%Topology.get_server_selection_timeout   s$    /##?>::rX   Nselector Callable[[Selection], Selection]	operationstrr   Optional[float]addressOptional[_Address]operation_idOptional[int]list[Server]c                J   K   |                                  }n|}t          s! j        r                                  d{V   j        4 d{V                       |||||           d{V } fd|D             cddd          d{V  S # 1 d{V swxY w Y   dS )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.
        Nc                j    g | ]/}t          t                              |j                            0S  )r
   r   get_server_by_addressr   ).0sdr   s     rC   
<listcomp>z+Topology.select_servers.<locals>.<listcomp>*  s@       IKVT77
CCDD  rX   )r   r   r   cleanup_monitorsr   _select_servers_loop)r   r   r   r   r   r   server_timeoutr{   s   `       rC   select_serverszTopology.select_servers  s     . $+!>>@@NN5N  	*D/ 	*''))))))))): 	 	 	 	 	 	 	 	(,(A(A.)\7) ) # # # # # #   Ob  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   -B
BBr   list[ServerDescription]c                  K   t          j                    }||z   }d}t          j        t          j                  r9t          t          t          j        |||| j	        | j	        j
        j                   | j                            ||| j        j                  }	|	s|dk    s||k    rt          j        t          j                  rMt          t          t          j        |||| j	        | j	        j
        j        |                     |                     t%          |                     |           d| d| j	                  |s`t          t          t          j        |||| j	        | j	        j
        j        t)          d|t          j                    z
  z            	           d
}|                                  d{V  |                                  t/          | j        t2          j                   d{V  | j                                         t          j                    }| j                            ||| j        j                  }	|	| j                                         |	S )z7select_servers() guts. Hold the lock when calling this.F)rL   r   r   operationIdtopologyDescriptionclientId)custom_selectorr   )rL   r   r   r   r   r   failurez, Timeout: zs, Topology Description: i  )rL   r   r   r   r   r   remainingTimeMSTN)time	monotonicr#   rh   ri   rj   r$   r&   STARTEDdescription_topology_settingsr]   rr   apply_selectorrn   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_waitingr{   s
             rC   r   zTopology._select_servers_loop.  s      n=#0?? 		(5=!#($($4)<I    #/>>gt~/M ? 
 
 & +	!||sX~~+8GG 
0 = D!)"+$0,0,<!%!1!D!Q $ 3 3H = =	 	 	 	 2**844wwwwcgcsww   " &,9A%' ,(,(8!-@M$'4>;K;K0K(L$M$M	 	 	 	 "&%%'''''''''##%%% #4?F4QRRRRRRRRR..000.""C"&"3"B"B'4>3Q #C # #S & +	Z 	**,,,""rX   deprioritized_serversOptional[list[Server]]r   c                  K   |                      |||||           d {V }t          ||          }t          |          dk    r|d         S t          j        |d          \  }}	|j        j        |	j        j        k    r|S |	S )NrQ   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
r   r   r   r   r   r   r   serversserver1server2s
             rC   _select_serverzTopology._select_serverz  s       ++i!97L
 
 
 
 
 
 
 
 "'+@AAw<<11:!=!44<'7<+GGGNNrX   c                  K   |                      ||||||           d{V }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 )zALike select_servers, but choose a random server if several match.r   Nr   rQ   )rL   r   r   r   r   r   rR   rS   )r   r   get_timeoutset_rttr   min_round_trip_timer#   rh   ri   rj   r$   r&   	SUCCEEDEDr   r]   r   )r   r   r   r   r   r   r   r   s           rC   select_serverzTopology.select_server  s       **$!% + 
 
 
 
 
 
 
 
  	BM&,@AAA#0?? 	(5?!#($($4)<I!-5a8!-5a8
 
 
 
 rX   r6   c                P   K   |                      t          ||||           d{V S )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        rC   select_server_by_addressz!Topology.select_server_by_address  sR      2 ''$% ( 
 
 
 
 
 
 
 
 	
rX   Fserver_descriptionr(   
reset_poolr:   interrupt_connectionsc           	       K   | j         }|j        |j                 }t          ||          rdS t	          | j         |          }|j        s|j        rU|j        t          j	        k    r@| j
                            |j                  }|r|j                                         d{V  ||k    }| j        r?|s=| j        J | j                            | j        j        |||j        | j        ff           || _         |                                  d{V  | j        r>|s<| j        J | j                            | j        j        || j         | j        ff           t/          j        t2          j                  rI|sGt7          t.          t8          j        | j        t=          |          t=          | j                              | j        rm|j        t          j         k    rX| j         j        tB          vrE| j        "                                 d{V  tF          s| j$        %                    | j                   | j&        '                                 dS )ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        NrN   )(rr   _server_descriptionsr   _is_stale_server_descriptionr2   is_readableis_server_type_knowntopology_typer/   Singler   getr   readyrb   re   rl   r`   "publish_server_description_changedr]   _update_serversrd   rt   r"   rh   ri   rj   r$   r%   ru   rv   r   rs   r.   r   r   r   appendr   
notify_all)	r   r   r   r   td_oldsd_oldnew_tdr   suppress_events	            rC   _process_changezTopology._process_change  s      ",-?-GH'0BCC 	F-d.?ASTT) 	*3	*8>8LP]Pd8d8d]&&'9'ABBF *k'')))))))))#55 	 	<+++LOF/1C1KTM^_   #""$$$$$$$$$ 	N 	<+++LOHT.0AB   $W]33 	N 	*:,$(LL#D$566     	> M$999!/7MMM#))+++++++++ >#**4+<=== 	""$$$$$rX   c                  K   | j         4 d{V  | j        r<| j                            |j                  r|                     |||           d{V  ddd          d{V  n# 1 d{V swxY w Y   |rD| j                            |j                  }|r%|j        	                    |           d{V  dS dS dS )z>Process a new ServerDescription after an hello call completes.N)r   )
r   r}   rr   
has_serverr   r  r   r  r   r   )r   r   r   r   r   s        rC   	on_changezTopology.on_change  s      : 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b | b 1 < <=O=W X X b**+=zK`aaaaaaaaa
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b 
	b  	U]&&'9'ABBF Uk''>S'TTTTTTTTTTT	U 	UU Us   AA&&
A03A0seedlistlist[tuple[str, Any]]c           	       K   | j         }|j        t          vrdS t          | j         |          | _         |                                  d{V  | j        r<| j        J | j                            | j        j	        || j         | j
        ff           t          j        t          j                  rIt          t          t           j        | j
        t%          |          t%          | j                              dS dS )z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        NrN   )rr   r   r.   r1   r  rd   re   rl   r`   rt   r]   r"   rh   ri   rj   r$   r%   ru   rv   )r   r  r  s      rC   _process_srv_updatezTopology._process_srv_update0  s      "'===FEdFWYabb""$$$$$$$$$ 	<+++LOHT.0AB   $W]33 	*:,$(LL#D$566     	 	rX   c                   K   | j         4 d{V  | j        r|                     |           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )z?Process a new list of nodes obtained from scanning SRV records.N)r   r}   r  )r   r  s     rC   on_srv_updatezTopology.on_srv_updateL  s       : 	9 	9 	9 	9 	9 	9 	9 	9| 9..x888888888	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9s   #A
AAOptional[Server]c                6    | 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     rC   r   zTopology.get_server_by_addressS  s     }  )))rX   c                    || j         v S rU   )r   r  s     rC   r  zTopology.has_server]  s    $-''rX   c                $  K   | j         4 d{V  | j        j        }|t          j        k    r	 ddd          d{V  dS t          |                                           d         j        cddd          d{V  S # 1 d{V swxY w Y   dS )z!Return primary's address or None.Nr   )r   rr   r   r/   ReplicaSetWithPrimaryr-   _new_selectionr   )r   r   s     rC   get_primaryzTopology.get_primary`  s      : 	N 	N 	N 	N 	N 	N 	N 	N -;M CCC	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N
 ,D,?,?,A,ABB1EM	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	Ns   A?+A??
B	B	set[_Address]c                `  K   | j         4 d{V  | j        j        }|t          j        t          j        fvr t                      cddd          d{V  S d t           ||                                                     D             cddd          d{V  S # 1 d{V swxY w Y   dS )z+Return set of replica set member addresses.Nc                    h | ]	}|j         
S r   )r   )r   r   s     rC   	<setcomp>z4Topology._get_replica_set_members.<locals>.<setcomp>w  s    OOO2BJOOOrX   )	r   rr   r   r/   r  ReplicaSetNoPrimarysetiterr  )r   r   r   s      rC   _get_replica_set_membersz!Topology._get_replica_set_membersj  s     
 : 	P 	P 	P 	P 	P 	P 	P 	P -;M31%   uu	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P POhht7J7J7L7L.M.M)N)NOOO	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	Ps   4B3B
B'*B'c                F   K   |                      t                     d{V S )z"Return set of secondary addresses.N)r$  r,   r   s    rC   get_secondarieszTopology.get_secondariesy  s-      223LMMMMMMMMMrX   c                F   K   |                      t                     d{V S )z Return set of arbiter addresses.N)r$  r+   r&  s    rC   get_arbiterszTopology.get_arbiters}  s-      223JKKKKKKKKKrX   Optional[ClusterTime]c                    | j         S )z1Return a document, the highest seen $clusterTime.r   r&  s    rC   max_cluster_timezTopology.max_cluster_time  s    %%rX   cluster_timeOptional[Mapping[str, Any]]c                \    |r'| j         r|d         | j         d         k    r|| _         d S d S d S )NclusterTimer,  r   r.  s     rC   _receive_cluster_time_no_lockz&Topology._receive_cluster_time_no_lock  sR      	6 *6.1G1VVV)5&&&	6 	6 WVrX   c                   K   | j         4 d {V  |                     |           d d d           d {V  d S # 1 d {V swxY w Y   d S rU   )r   r3  r2  s     rC   receive_cluster_timezTopology.receive_cluster_time  s      : 	= 	= 	= 	= 	= 	= 	= 	=..|<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	=s   9
AA   	wait_timer   c                   K   | j         4 d{V  |                                  t          | j        |           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )z=Wake all monitors, wait for at least one to check its server.N)r   r   r   r   )r   r7  s     rC   request_check_allzTopology.request_check_all  s     : 	? 	? 	? 	? 	? 	? 	? 	?##%%%"4?I>>>>>>>>>	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	?s   0A
A Ac                f    | 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.
        )rr   r   r/   r   known_serversreadable_serversr&  s    rC   data_bearing_serverszTopology.data_bearing_servers  s0    
 *m.BBB$22 11rX   c           	       K   g }| j         4 d {V  |                                 D ]G}| j        |j                 }|                    ||j        j                                        f           H	 d d d           d {V  n# 1 d {V swxY w Y   |D ]r\  }}	 |j                            |           d {V  '# t          $ r?}t          |d|dd           }|                     |j        j        |           d {V   d }~ww xY wd S )Nr   F)r   r=  r   r   r  r   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )r   r   r   r   
generationexcctxs          rC   update_poolzTopology.update_pool  s     : 	H 	H 	H 	H 	H 	H 	H 	H//11 H Hrz2(C(C(E(EFGGGGH	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H #* 	 	FJk66zBBBBBBBBBB   #CJtDD''(:(BCHHHHHHHHH	 	s*   AB
BB B<<
D:D  Dc           	     "  K   | j         4 d{V  | j        }| j                                        D ]B}|                                 d{V  t
          s| j                            |j                   C| j        	                                | _        | j        
                                                                D ] \  }}|| j        v r|| j        |         _        !| j        rE| j                                         d{V  t
          s| j                            | j                   d| _        d| _        ddd          d{V  n# 1 d{V swxY w Y   | j        r| j        J t%          t&          j        i | j        j        | j        j        | j        j        | j        j                  | _        | j                            | j        j        || j        | j        ff           | j                            | j        j        | j        ff           t=          j        t@          j!                  rmtE          t<          tF          j$        | j        tK          |          tK          | j                             tE          t<          tF          j&        | j                   | j'        s| j        ra| j(                                         | j(        )                    d           d{V  tU          tW          j,        | j                             dS dS )zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        NFTrN   rK   rQ   )-r   rr   r   r   r   r   r   r  _monitorr   r{   itemsr   r   r}   r~   rd   re   r0   r/   rs   rq   max_set_versionmax_election_idr   rl   r`   rt   r]   publish_topology_closedr"   rh   ri   rj   r$   r%   ru   rv   STOP_TOPOLOGYrb   rf   joinrD   r   r   )r   old_tdr   r   r   s        rC   r   zTopology.close  s     
 : 	  	  	  	  	  	  	  	 &F-..00 @ @llnn$$$$$$$ @'..v??? !% 1 7 7 9 9D#0DDFFLLNN < <dm++9;DM'*6   B'--///////// B'..t/@AAA DLDL)	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 .  	^<+++ 3%!2!1!1!4! !D LOH))	 	 	 LdoEHYG[\]]]$W]33 
	*:,$(LL#D$566    &8&FSWSd     	<4#3 	<"((***(--a000000000 T\!:!:;;;;;		< 	<s   D(E


EEr0   c                    | j         S rU   )rr   r&  s    rC   r   zTopology.description  s      rX   list[_ServerSession]c                4    | j                                         S )z"Pop all session ids from the pool.)r   pop_allr&  s    rC   pop_all_sessionszTopology.pop_all_sessions  s    !))+++rX   session_timeout_minutesr   c                6    | j                             |          S )z>Start or resume a server session, or raise ConfigurationError.)r   get_server_session)r   rV  s     rC   rX  zTopology.get_server_session  s    !445LMMMrX   server_sessionc                :    | j                             |           d S rU   )r   return_server_session)r   rY  s     rC   r[  zTopology.return_server_session  s    00@@@@@rX   r)   c                4    t          j        | j                  S )zmA Selection object, initially including all known servers.

        Hold the lock when calling this.
        )r)   from_topology_descriptionrr   r&  s    rC   r  zTopology._new_selection
  s    
 243DEEErX   c                R  K   | j         rt          d          | j        sd| _        |                                  d{V  | j        s| j        r| j                                         | j        r,| j	        j
        t          v r| j                                         | j        j        rJ|                     t          | j        d         t#          d| j        dd                               d{V  | j                                        D ]}|                                 d{V  dS )z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z'Cannot use AsyncMongoClient after closeTNr   rQ      )ok	serviceIdmaxWireVersion)r~   r   r}   r  rd   rb   rf   r   r   r   r   r.   rn   r   r  r(   r|   r   r]   r   r   r   r   s     rC   r   zTopology._ensure_opened  sv     
 < 	N"#LMMM| 	DL&&(((((((((  .4#7 .&++---   )d&6&DH^&^&^!&&(((~+ **%,Q/QT5FZ\]]^^          m**,, 	  	 F++--	  	 rX   err_ctxrB  c                b   | j                             |          }|dS |j                            |j        |j                  rdS |j        j        }|j        }d }|rDt          |d          r4t          |j        t                    r|j                            d          }t          ||          S )NTdetailstopologyVersion)r   r  _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancerf  dict _is_stale_error_topology_version)r   r   rd  r   cur_tvrm  error_tvs          rC   _is_stale_errorzTopology._is_stale_error2  s    ""7++>4<(()@'BTUU 	4 #4 	@WUI.. 	@%-.. @ =,,->??/AAArX   c                  K   |                      ||          rd S | j        |         }|j        }|j        }| j        j        r|s	|j        sd S t          |t                    r	|j        rd S t          |t                    rd S t          |t          t          f          r8t          |d          r|j        }n4t          |t                    rdnd }|j                            d|          }|t           j        v r|t           j        v }| j        j        s*|                     t)          ||                     d {V  |s|j        dk    r|                    |           d {V  |                                 d S |j        sS| j        j        s*|                     t)          ||                     d {V  |                    |           d {V  d S d S t          |t0                    rt          |t2                    rd S | j        j        s*|                     t)          ||                     d {V  |                    |           d {V  |j                                         d S d S )Ncodei{'  rm     )rt  r   rm  rk  rn   r   completed_handshakero  r   r   r   r   rn  rv  rf  r  r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr  r(   max_wire_versionr   request_checkr   r   rI  cancel_check)	r   r   rd  r   rm  rk  err_codedefaultis_shutting_downs	            rC   _handle_errorzTopology._handle_errorF  s     11 	Fw''
 >' 	
 	7C^ 	Fe^,, 3	+1L 3	+
 Fz** -	+F1ABCC *	+ uf%% > : $.e_#E#EO%%4 =,,VW==><<<#+~/M#M ~3 X../@PU/V/V/VWWWWWWWWW# 3(@A(E(E ,,z222222222$$&&&&&0 /~3 X../@PU/V/V/VWWWWWWWWWll:.........../ / 011 	+%!677  >/ T**+<WE+R+R+RSSSSSSSSS,,z********* O((*****	+ 	+rX   c                   K   | j         4 d{V  |                     ||           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )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   rd  s      rC   rC  zTopology.handle_error  s       : 	7 	7 	7 	7 	7 	7 	7 	7$$Wg666666666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   A  
A
A
c                f    | j                                         D ]}|                                 dS )z3Wake all monitors. Hold the lock when calling this.N)r   r   r}  rc  s     rC   r   zTopology._request_check_all  s>    m**,, 	# 	#F  """"	# 	#rX   c           	       K   | j                                                                         D ])\  }}|| j        vr| j                            || |                     |          | j                  }d}| j        r | j        t          j
        | j                  }t          ||                     |          || j        | j        |          }|| j        |<   |                                 d{V  | j        |         j        j        }|| j        |         _        ||j        k    r0| j        |         j                            |j                   d{V  +t)          | j                                                  D ]y\  }}| j                             |          sZ|                                 d{V  t.          s| j                            |j                   | j                            |           zdS )zrSync our Servers from TopologyDescription.server_descriptions.

        Hold the lock while calling this.
        )r   topologyr   rG   N)r   r   monitortopology_id	listenersevents)rr   r{   rJ  r   rn   monitor_class_create_pool_for_monitorrb   re   r   r   r   _create_pool_for_serverr]   r`   r   r   is_writabler   update_is_writablerz   r  r   r   r   r  rI  pop)r   r   r   r  rV   r   was_writables          rC   r  zTopology._update_servers  s     
  ,@@BBHHJJ 	Y 	YKGRdm++.66')!66w??&*n	 7   ' 5DL,D";t|44D')55g>># $ 1"o   *0g&kkmm########  $}W5AM57g&22>11-05HHXXXXXXXXX#DM$7$7$9$9:: 	+ 	+OGV$//88 +llnn$$$$$$$ @'..v???!!'***	+ 	+rX   r   c                Z    | j                             || j         j        | j                  S )N)	client_id)rn   
pool_classpool_optionsr]   r  s     rC   r  z Topology._create_pool_for_server  s0    ~((T^0D<M ) 
 
 	
rX   c                    | j         j        }t          |j        |j        |j        |j        |j        |j        |j        d|j	        	  	        }| j         
                    ||d| j                  S )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_apiT)is_sdamr  )rn   r  r'   r  _ssl_contextr  r_   r  r  r  r  r]   )r   r   optionsmonitor_pool_optionss       rC   r  z!Topology._create_pool_for_monitor  s    .-
  +#3"2,(/(K#4O>)
 
 
 
 
 
 ~(()44CT ) 
 
 	
rX   c                   | 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dS d|z  S d| d| dS t          | j         	                                          }t          | j         	                                
                                          }|s'|r d	                    || j        j                  S d
|z  S |d         j        t          fd|dd         D                       }|rDd|z  S |r,t!          |                              | j                  sd|z  S t'                    S d                    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    V  d S rU   rw  )r   r   rm  s     rC   	<genexpr>z*Topology._error_message.<locals>.<genexpr>  s*      GGv|u,GGGGGGrX   rQ   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c              3  L   K   | ]}|j         	t          |j                   V   d S rU   )rm  r   )r   r   s     rC   r  z*Topology._error_message.<locals>.<genexpr>  s3      XXf6<XFL 1 1XXXXXXrX   )rr   r   r/   r  r!  Shardedr;  r-   rz   r{   r   formatrn   rq   rm  allr"  intersectionr|   r   rO  )r   r   is_replica_setserver_plural	addressesr   samerm  s          @rC   r   zTopology._error_message  s   
 *8/-=
 

  	&1MM,0EEE&MM%M* '	Y333! H<<7-GGH]HHXHHHHT.BBDDEEI4,@@BBIIKKLLG =! =FMM%7  
 -}<< AJ$EGGGG7122;GGGGGD Y=,}<<! #i..*E*EdFZ*[*[ FHQR
 5zz!xxXXXXXXXXrX   c                   K   g }	 | j         r3|                    | j                                                    | j         3n# t          $ r Y nw xY wt	          j        d |D             ddi d {V  d S )Nc                6    g | ]}|                                 S r   )rO  )r   ts     rC   r   z-Topology.cleanup_monitors.<locals>.<listcomp>   s     777Aqvvxx777rX   return_exceptionsT)r   r  r  
IndexErrorasynciogather)r   taskss     rC   r   zTopology.cleanup_monitors  s      	% 8T04466777 % 8 	 	 	D	n77777P4PPPPPPPPPPPs   :A 
AAc                L    d}| j         sd}d| j        j         d| | j        dS )N zCLOSED < >)r}   	__class____name__rr   )r   msgs     rC   __repr__zTopology.__repr__"  s<    | 	CH4>*HHSH$2CHHHHrX   >tuple[tuple[_Address, ...], Optional[str], Optional[str], str]c                x    | j         }t          t          |j                            |j        |j        |j        fS )zDThe properties to use for AsyncMongoClient/Topology equality checks.)rn   tuplesortedrw   rq   r   srv_service_name)r   tss     rC   eq_propszTopology.eq_props(  s2    ^fRX&&'')<bgrGZ[[rX   otherobjectc                    t          || j                  r*|                                 |                                k    S t          S rU   )ro  r  r  NotImplemented)r   r  s     rC   __eq__zTopology.__eq__-  s9    eT^,, 	7==??enn&6&666rX   c                D    t          |                                           S rU   )hashr  r&  s    rC   __hash__zTopology.__hash__2  s    DMMOO$$$rX   )rG   r4   )r9   r   )r9   r   )NNN)r   r   r   r   r   r   r   r   r   r   r9   r   )r   r   r   r   r   r   r   r   r   r   r9   r   )NNNN)r   r   r   r   r   r   r   r   r   r   r   r   r9   r   )NN)
r   r6   r   r   r   r   r   r   r9   r   )FF)r   r(   r   r:   r   r:   r9   r   )r  r  r9   r   )r   r6   r9   r  )r   r6   r9   r:   )r9   r   )r   r   r9   r  )r9   r  )r9   r*  )r.  r/  r9   r   )r6  )r7  r   r9   r   )r9   r   )r9   r0   )r9   rR  )rV  r   r9   r   )rY  r   r9   r   )r9   r)   )r   r6   rd  rB  r9   r:   )r   r6   rd  rB  r9   r   )r   r6   r9   r   )r   r   r9   r   )r9   r   )r9   r  )r  r  r9   r:   )r9   r   )1r  
__module____qualname____doc__r   r   r   r   r   r   r   r   r  r  r  r  r   r  r  r$  r'  r)  r-  r3  r5  r9  r=  rG  r   propertyr   rU  rX  r[  r  r   rt  r  rC  r   r  r  r  r   r   r  r  r  r  r   rX   rC   rF   rF   h   sN       44j4 j4 j4 j4X%( %( %( %(N    59&*&*' ' ' ' 'RJ# J# J# J#` 59&*8<&*    2 59&*8<&*         L 37&*
 
 
 
 
H !&+	C% C% C% C% C%P !&+	U U U U U2   89 9 9 9* * * *( ( ( (N N N NP P P PN N N NL L L L& & & &6 6 6 6= = = =? ? ? ? ?2 2 2 2   "A< A< A< A<F ! ! ! X!, , , ,N N N NA A A AF F F F       BB B B B(B+ B+ B+ B+H7 7 7 7# # # #
*+ *+ *+ *+X
 
 
 


 
 
 
,8Y 8Y 8Y 8YtQ Q Q QI I I I\ \ \ \
   
% % % % % %rX   rF   c                      e Zd ZdZddZdS )rB  z.An error with context for SDAM error handling.rm  BaseExceptionr|  r   rj  ry  r:   rk  Optional[ObjectId]c                L    || _         || _        || _        || _        || _        d S rU   )rm  r|  rj  ry  rk  )r   rm  r|  rj  ry  rk  s         rC   r   z_ErrorContext.__init__9  s.     
 0.#6 $rX   N)
rm  r  r|  r   rj  r   ry  r:   rk  r  )r  r  r  r  r   r   rX   rC   rB  rB  6  s.        88% % % % % %rX   rB  
current_tvr/  rs  c                Z    | |dS | d         |d         k    rdS | d         |d         k    S )z9Return True if the error's topologyVersion is <= current.NF	processIdcounterr   )r  rs  s     rC   rq  rq  H  sC     X-u+(;"777ui HY$777rX   
current_sdr(   new_sdc                v    | j         |j         }}||dS |d         |d         k    rdS |d         |d         k    S )z4Return True if the new topologyVersion is < current.NFr  r  )rl  )r  r  r  new_tvs       rC   r   r   S  sO    #4f6MJV^u+&"555ui 6)#444rX   
candidatesr   r   r   c                0    s| S fd| D             }|p| S )zBFilter out deprioritized servers from a list of server candidates.c                    g | ]}|v|	S r   r   )r   r   r   s     rC   r   z#_filter_servers.<locals>.<listcomp>d  s$    WWW66AV3V3V3V3V3VrX   r   )r  r   filtereds    ` rC   r   r   ]  s9     ! WWWWZWWWH !z!rX   )r7   r8   r9   r:   )r  r/  rs  r/  r9   r:   )r  r(   r  r(   r9   r:   rU   )r  r   r   r   r9   r   )\r  
__future__r   r  ri   r   r=   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   rD   rF   rB  rq  r   r   r   rX   rC   <module>r     s   C B " " " " " "   				   



          H H H H H H H H H H H H H H H H D D D D D D D D D D D D R R R R R R R R @ @ @ @ @ @ @ @ * * * * * * . . . . . .
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                
              - , , , , , 8 8 8 8 8 8                            6>>>>>>55555555s44>>())   "K% K% K% K% K% K% K% K%\% % % % % % % %$8 8 8 85 5 5 5 OS
" 
" 
" 
" 
" 
" 
"rX   