o
    h                     @  s  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rddlJmKZK ddlLmMZM ddlNmOZOmPZP dZQeReeSjTZUd1ddZVG dd dZWG dd  d ZXd2d$d%ZYd3d)d*ZZ	d4d5d/d0Z[dS )6z<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                 C  sF   |  }|sdS 	 z|  }W n tjy   Y dS w |\}}||  q)NFT)
get_nowaitqueueEmpty)r6   qeventfnargs rA   P/var/www/html/venv/lib/python3.10/site-packages/pymongo/asynchronous/topology.pyprocess_events_queueW   s   rC   c                   @  s  e Zd ZdZdddZddd	ZdddZ			ddddZdddZ				ddd"d#Z					ddd$d%Z
		ddd'd(Z	)	)ddd/d0Z	)	)ddd1d2Zdd5d6Zdd7d8Zdd:d;Zdd<d=Zdd>d?ZddAdBZddCdDZddEdFZddHdIZddLdMZddNdOZdddSdTZddUdVZddWdXZddYdZZedd\d]Zdd_d`ZddcddZ ddfdgZ!ddidjZ"ddkdlZ#ddodpZ$ddqdrZ%ddsdtZ&ddudvZ'ddwdxZ(ddzd{Z)dd|d}Z*dd~dZ+dddZ,dddZ-dddZ.dddZ/dddZ0dS )Topologyz*Monitor a topology of one or more servers.topology_settingsr3   c                   s  |j | _ |jj| _| jd uo| jj| _| jd uo| jj| _d | _d | _	| js)| jr0t
jdd| _ttjr?tttj| j d | jrU| jd usIJ | j| jj| j ff || _t| | |jd d |}|| _ttji d d d | j}| jr| jd us~J | j| jj|| j| j ff ttjrtttj| j || jd |jD ].}| jr| jd usJ | j| jj || j ff ttjrtttj!| j |d |d d qt"|# | _$d| _%d| _&t' | _(t)| j(t*r| jj+nd | _,i | _-d | _.d | _/t0 | _1| js| jr-| jd usJ d fdd}t2j3t4j5t4j6|dd}t78| j|j9 || _	|:  d | _;| jj<d urC| jj=sCt>| | j| _;g | _?d S )Nd   )maxsizemessage
topologyIdrI   rJ   ZpreviousDescriptionZnewDescriptionr      )rI   rJ   
serverHost
serverPortFr8   r9   c                     s
   t  S N)rC   rA   weakrA   rB   target   s   z!Topology.__init__.<locals>.targetZpymongo_events_thread)intervalZmin_intervalrR   name)r8   r9   )@_topology_idZ_pool_options_event_listeners
_listenersZenabled_for_server_publish_serverZenabled_for_topology_publish_tp_events_Topology__events_executorr;   Queuer!   isEnabledForloggingDEBUGr#   r$   ZSTART_TOPOLOGYputZpublish_topology_opened	_settingsr/   Zget_topology_typeZget_server_descriptionsreplica_set_name_descriptionr.   Unknown$publish_topology_description_changedTOPOLOGY_CHANGEseedsZpublish_server_openedZSTART_SERVERlistserver_descriptions_seed_addresses_opened_closedr    _lockr   _IS_SYNCZcondition_class
_condition_servers_pid_max_cluster_timer   _session_poolr   ZAsyncPeriodicExecutorr   ZEVENTS_QUEUE_FREQUENCYMIN_HEARTBEAT_INTERVALweakrefrefcloseopen_srv_monitorfqdnload_balancedr   _monitor_tasks)selfrE   Ztopology_descriptionZ
initial_tdseedrR   executorrA   rP   rB   __init__k   s   
	
	

zTopology.__init__r8   Nonec              	     s  t  }| jdu r|| _nU|| jkrc|| _tjdd dkr%dtfi}nddi}tj	di | | j4 I dH  | j	
 D ]	}| I dH  q?| j  W d  I dH  n1 I dH s^w   Y  | j4 I dH  |  I dH  W d  I dH  dS 1 I dH sw   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   )      Z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getpidrq   sysversion_info_pymongo_dirwarningswarnrm   rp   valuesrw   rs   reset_ensure_opened)r}   pidkwargsserverrA   rA   rB   rx      s,   

(.zTopology.openfloatc                 C  s   t  }|d u r| jjS |S rO   )r
   	remainingra   server_selection_timeout)r}   timeoutrA   rA   rB   get_server_selection_timeout   s   z%Topology.get_server_selection_timeoutNselector Callable[[Selection], Selection]	operationstrr   Optional[float]addressOptional[_Address]operation_idOptional[int]list[Server]c              	     s   |du r
   }n|}ts jr  I dH   j4 I dH    |||||I dH } fdd|D W  d  I dH  S 1 I dH sEw   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                   s   g | ]}t t |jqS rA   )r	   r   get_server_by_addressr   .0sdr}   rA   rB   
<listcomp>*  s    z+Topology.select_servers.<locals>.<listcomp>)r   rn   r|   cleanup_monitorsrm   _select_servers_loop)r}   r   r   r   r   r   Zserver_timeoutri   rA   r   rB   select_servers  s   




0zTopology.select_serversr   list[ServerDescription]c           
        s^  t  }|| }d}ttjr!tttj|||| j	| j	j
jd | jj||| jjd}	|	s|dks6||kr`ttjrPtttj|||| j	| j	j
j| |d t| | d| d| j	|s}tttj|||| j	| j	j
jtd|t    d	 d
}|  I dH  |   t| jtjI dH  | j  t  }| jj||| jjd}	|	r.| j  |	S )z7select_servers() guts. Hold the lock when calling this.F)rI   r   r   operationIdtopologyDescriptionclientId)Zcustom_selectorr   )rI   r   r   r   r   r   Zfailurez, Timeout: zs, Topology Description: i  )rI   r   r   r   r   r   ZremainingTimeMSTN)time	monotonicr"   r]   r^   r_   r#   r%   ZSTARTEDdescription_topology_settingsrU   rc   Zapply_selectorra   Zserver_selectorZFAILED_error_messager   ZWAITINGintr   _request_check_allr   ro   r   rt   Zcheck_compatible)
r}   r   r   r   r   r   nowZend_timeZlogged_waitingri   rA   rA   rB   r   .  sp   	






-zTopology._select_servers_loopdeprioritized_serversOptional[list[Server]]r   c           
        s`   |  |||||I d H }t||}t|dkr|d S t|d\}}	|jj|	jjkr.|S |	S )NrL   r   r   )r   _filter_serverslenrandomsamplepoolZoperation_count)
r}   r   r   r   r   r   r   serversZserver1Zserver2rA   rA   rB   _select_serverz  s   	


zTopology._select_serverc                   sx   | j ||||||dI dH }t rt|jj ttj	r:t
ttj|||| j| jjj|jjd |jjd d	 |S )zALike select_servers, but choose a random server if several match.r   Nr   rL   )rI   r   r   r   r   r   rM   rN   )r   r
   Zget_timeoutZset_rttr   Zmin_round_trip_timer"   r]   r^   r_   r#   r%   Z	SUCCEEDEDr   rU   r   )r}   r   r   r   r   r   r   r   rA   rA   rB   select_server  s0   


zTopology.select_serverr5   c                   s   | j t||||dI dH 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   rA   rA   rB   select_server_by_address  s   z!Topology.select_server_by_addressFserver_descriptionr'   
reset_poolr9   interrupt_connectionsc           	        sh  | j }|j|j }t||rdS t| j |}|js#|jr4|jtj	kr4| j
|j}|r4|j I dH  ||k}| jrT|sT| jdusDJ | j| jj|||j| jff || _ |  I dH  | jry|sy| jdusjJ | j| jj|| j | jff ttjr|stttj| j|| j d | jr|jtjkr| j jt vr| j! I dH  t"s| j#$| j | j%&  dS )ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        NrK   )'rc   Z_server_descriptionsr   _is_stale_server_descriptionr1   Zis_readableZis_server_type_knowntopology_typer.   Singlerp   getr   readyrX   rZ   r`   rW   Z"publish_server_description_changedrU   _update_serversrY   re   r!   r]   r^   r_   r#   r$   rf   ry   rd   r-   rw   rn   r|   appendro   
notify_all)	r}   r   r   r   td_oldZsd_oldZnew_tdr   Zsuppress_eventrA   rA   rB   _process_change  sZ   



zTopology._process_changec              	     s   | j 4 I dH  | jr| j|jr| |||I dH  W d  I dH  n1 I dH s-w   Y  |rI| j|j}|rK|jj	|dI dH  dS dS dS )z>Process a new ServerDescription after an hello call completes.N)r   )
rm   rk   rc   
has_serverr   r   rp   r   r   r   )r}   r   r   r   r   rA   rA   rB   	on_change  s   	(zTopology.on_changeseedlistlist[tuple[str, Any]]c                   s   | j }|jtvrdS t| j || _ |  I dH  | jr2| jdus#J | j| jj	|| j | j
ff ttjrFtttj| j
|| j d dS dS )z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        NrK   )rc   r   r-   r0   r   rY   rZ   r`   rW   re   rU   r!   r]   r^   r_   r#   r$   rf   )r}   r   r   rA   rA   rB   _process_srv_update0  s,   

zTopology._process_srv_updatec              	     sn   | j 4 I dH " | jr| |I dH  W d  I dH  dS W d  I dH  dS 1 I dH s0w   Y  dS )z?Process a new list of nodes obtained from scanning SRV records.N)rm   rk   r   )r}   r   rA   rA   rB   on_srv_updateL  s   .zTopology.on_srv_updateOptional[Server]c                 C     | 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.
        )rp   r   r}   r   rA   rA   rB   r   S  s   zTopology.get_server_by_addressc                 C  s
   || j v S rO   )rp   r   rA   rA   rB   r   ]  s   
zTopology.has_serverc              	     s|   | j 4 I dH ) | jj}|tjkr	 W d  I dH  dS t|  d jW  d  I dH  S 1 I dH s7w   Y  dS )z!Return primary's address or None.Nr   )rm   rc   r   r.   ReplicaSetWithPrimaryr,   _new_selectionr   )r}   r   rA   rA   rB   get_primary`  s   
0zTopology.get_primaryset[_Address]c              	     s   | j 4 I dH 1 | jj}|tjtjfvr"t W  d  I dH  S dd t||  D W  d  I dH  S 1 I dH s?w   Y  dS )z+Return set of replica set member addresses.Nc                 S  s   h | ]}|j qS rA   )r   r   rA   rA   rB   	<setcomp>w  s    z4Topology._get_replica_set_members.<locals>.<setcomp>)	rm   rc   r   r.   r   ReplicaSetNoPrimarysetiterr   )r}   r   r   rA   rA   rB   _get_replica_set_membersj  s   0z!Topology._get_replica_set_membersc                      |  tI dH S )z"Return set of secondary addresses.N)r   r+   r   rA   rA   rB   get_secondariesy     zTopology.get_secondariesc                   r   )z Return set of arbiter addresses.N)r   r*   r   rA   rA   rB   get_arbiters}  r   zTopology.get_arbitersOptional[ClusterTime]c                 C     | j S )z1Return a document, the highest seen $clusterTime.rr   r   rA   rA   rB   max_cluster_time     zTopology.max_cluster_timecluster_timeOptional[Mapping[str, Any]]c                 C  s.   |r| j r|d | j d kr|| _ d S d S d S )NZclusterTimer   r}   r   rA   rA   rB   _receive_cluster_time_no_lock  s   
z&Topology._receive_cluster_time_no_lockc              	     sL   | j 4 I d H  | | W d   I d H  d S 1 I d H sw   Y  d S rO   )rm   r   r   rA   rA   rB   receive_cluster_time  s   .zTopology.receive_cluster_time   	wait_timer   c              	     s\   | j 4 I dH  |   t| j|I dH  W d  I dH  dS 1 I dH s'w   Y  dS )z=Wake all monitors, wait for at least one to check its server.N)rm   r   r   ro   )r}   r   rA   rA   rB   request_check_all  s
   .zTopology.request_check_allc                 C  s   | 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.
        )rc   r   r.   r   known_serversZreadable_serversr   rA   rA   rB   data_bearing_servers  s   zTopology.data_bearing_serversc                   s   g }| j 4 I d H # |  D ]}| j|j }|||jj f qW d   I d H  n1 I d H s3w   Y  |D ]/\}}z|j|I d H  W q: t	yi } zt
|d|dd }| |jj|I d H   d }~ww d S )Nr   F)rm   r   rp   r   r   r   genZget_overallZremove_stale_socketsr   _ErrorContexthandle_errorr   )r}   r   r   r   Z
generationexcctxrA   rA   rB   update_pool  s$   (zTopology.update_poolc              	     s  | j 4 I dH ] | j}| j D ]}| I dH  ts#| j|j q| j	 | _| j
  D ]\}}|| jv r@|| j| _q1| jrU| j I dH  tsU| j| j d| _d| _W d  I dH  n1 I dH skw   Y  | jr| jduszJ 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t j!rt"tt#j$| j|| jd t"tt#j%| jd | j&s| jr| j'  | j'(dI dH  t)t*+| j dS dS )zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        NFTrK   rH   rL   ),rm   rc   rp   r   rw   rn   r|   r   _monitorr   ri   itemsr   ry   rk   rl   rY   rZ   r/   r.   rd   rb   Zmax_set_versionZmax_election_idr   r`   rW   re   rU   Zpublish_topology_closedr!   r]   r^   r_   r#   r$   rf   ZSTOP_TOPOLOGYrX   r[   joinrC   ru   rv   )r}   Zold_tdr   r   r   rA   rA   rB   rw     sn   
(


zTopology.closer/   c                 C  r   rO   )rc   r   rA   rA   rB   r     r   zTopology.descriptionlist[_ServerSession]c                 C  s
   | j  S )z"Pop all session ids from the pool.)rs   pop_allr   rA   rA   rB   pop_all_sessions  s   
zTopology.pop_all_sessionssession_timeout_minutesr   c                 C  r   )z>Start or resume a server session, or raise ConfigurationError.)rs   get_server_session)r}   r  rA   rA   rB   r    s   zTopology.get_server_sessionserver_sessionc                 C  s   | j | d S rO   )rs   return_server_session)r}   r  rA   rA   rB   r    s   zTopology.return_server_sessionr(   c                 C  s   t | jS )zmA Selection object, initially including all known servers.

        Hold the lock when calling this.
        )r(   Zfrom_topology_descriptionrc   r   rA   rA   rB   r   
  s   zTopology._new_selectionc              	     s   | j rtd| jsGd| _|  I dH  | js| jr | j  | jr.| j	j
tv r.| j  | jjrG| t| jd td| jddI dH  | j D ]	}| I dH  qLdS )z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z'Cannot use AsyncMongoClient after closeTNr   rL      )okZ	serviceIdZmaxWireVersion)rl   r   rk   r   rY   rX   r[   rx   ry   r   r   r-   ra   r{   r   r'   rj   r   rU   rp   r   r}   r   rA   rA   rB   r     s(   


zTopology._ensure_openederr_ctxr   c                 C  sp   | j |}|d u rdS |j|j|jrdS |jj}|j}d }|r3t	|dr3t
|jtr3|jd}t||S )NTdetailsZtopologyVersion)rp   r   _poolZstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancer  dict _is_stale_error_topology_version)r}   r   r
  r   Zcur_tvr  error_tvrA   rA   rB   _is_stale_error2  s   
zTopology._is_stale_errorc           	        s  |  ||r	d S | j| }|j}|j}| jjr|s|jsd S t|tr)|jr)d S t|t	r0d S t|t
tfrt|dr@|j}nt|t
rGdnd }|jd|}|tjv r|tjv }| jjsj| t||dI d H  |sq|jdkry||I d H  |  d S |js| jjs| t||dI d H  ||I d H  d S d S t|trt|trd S | jjs| t||dI d H  ||I d H  |j  d S d S )Ncodei{'  r     )r  rp   r  r  ra   r{   completed_handshaker  r   r   r   r   r  r  r  r   r   Z_NOT_PRIMARY_CODESZ_SHUTDOWN_CODESr   r'   max_wire_versionr   request_checkr   r   r   Zcancel_check)	r}   r   r
  r   r  r  Zerr_codedefaultZis_shutting_downrA   rA   rB   _handle_errorF  sJ   


	



zTopology._handle_errorc              	     sT   | j 4 I dH  | ||I dH  W d  I dH  dS 1 I dH s#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)rm   r  )r}   r   r
  rA   rA   rB   r     s   .zTopology.handle_errorc                 C  s   | j  D ]}|  qdS )z3Wake all monitors. Hold the lock when calling this.N)rp   r   r  r	  rA   rA   rB   r     s   
zTopology._request_check_allc              	     s*  | j   D ]b\}}|| jvrK| jj|| | || jd}d}| jr/| jdur/t	
| j}t|| ||| j| j|d}|| j|< | I dH  q| j| jj}|| j| _||jkrj| j| j|jI dH  qt| j D ] \}}| j |s| I dH  ts| j|j | j| qrdS )zrSync our Servers from TopologyDescription.server_descriptions.

        Hold the lock while calling this.
        )r   Ztopologyr   rE   N)r   r   monitorZtopology_idZ	listenersevents)rc   ri   r   rp   ra   Zmonitor_class_create_pool_for_monitorrX   rZ   ru   rv   r   _create_pool_for_serverrU   rW   rx   r   is_writabler   Zupdate_is_writablerh   r   rw   rn   r|   r   r   pop)r}   r   r   r  rQ   r   Zwas_writablerA   rA   rB   r     sF   

	
zTopology._update_serversr   c                 C  s   | j j|| j j| jdS )N)	client_id)ra   
pool_classpool_optionsrU   r   rA   rA   rB   r"    s   z Topology._create_pool_for_serverc                 C  sH   | j j}t|j|j|j|j|j|j|jd|j	d	}| j j
||d| jdS )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesZevent_listenersappnamedriverZpause_enabled
server_api)	handshaker%  )ra   r'  r&   r(  _ssl_contextr+  rV   r,  r-  r.  r&  rU   )r}   r   optionsZmonitor_pool_optionsrA   rA   rB   r!    s   
z!Topology._create_pool_for_monitorc                   s  | j jtjtjfv }|rd}n| j jtjkrd}nd}| j jr4|tu r+|r'dS d| S d| d| dS t| j 	 }t| j 	 
 }|sT|rPd	|| jjS d
| S |d j t fdd|dd D }|r du rrd| S |rt|| jsd| S t S ddd |D S )zeFormat an error message if server selection fails.

        Hold the lock when calling this.
        zreplica set membersZ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  s    | ]}|j  kV  qd S rO   r  r   r   r  rA   rB   	<genexpr>  s    z*Topology._error_message.<locals>.<genexpr>rL   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c                 s  s     | ]}|j rt|j V  qd S rO   )r  r   r3  rA   rA   rB   r4    s    )rc   r   r.   r   r   ZShardedr   r,   rh   ri   r   formatra   rb   r  allr   intersectionrj   r   r   )r}   r   Zis_replica_setZserver_plural	addressesr   ZsamerA   r  rB   r     sH   
zTopology._error_messagec                   s^   g }z| j r|| j   | j sW n	 ty   Y nw tjdd |D ddiI d H  d S )Nc                 S  s   g | ]}|  qS rA   )r   )r   trA   rA   rB   r      s    z-Topology.cleanup_monitors.<locals>.<listcomp>Zreturn_exceptionsT)r|   r   r$  
IndexErrorasyncioZgather)r}   tasksrA   rA   rB   r     s   $zTopology.cleanup_monitorsc                 C  s*   d}| j sd}d| jj d| | jdS )N zCLOSED < >)rk   	__class____name__rc   )r}   msgrA   rA   rB   __repr__"  s   zTopology.__repr__>tuple[tuple[_Address, ...], Optional[str], Optional[str], str]c                 C  s"   | j }tt|j|j|j|jfS )zDThe properties to use for AsyncMongoClient/Topology equality checks.)ra   tuplesortedrg   rb   rz   Zsrv_service_name)r}   tsrA   rA   rB   eq_props(  s   zTopology.eq_propsotherobjectc                 C  s    t || jr|  | kS tS rO   )r  rB  rJ  NotImplemented)r}   rK  rA   rA   rB   __eq__-  s   zTopology.__eq__c                 C  s   t |  S rO   )hashrJ  r   rA   rA   rB   __hash__2  s   zTopology.__hash__)rE   r3   )r8   r   )r8   r   )NNN)r   r   r   r   r   r   r   r   r   r   r8   r   )r   r   r   r   r   r   r   r   r   r   r8   r   )NNNN)r   r   r   r   r   r   r   r   r   r   r   r   r8   r   )NN)
r   r5   r   r   r   r   r   r   r8   r   )FF)r   r'   r   r9   r   r9   r8   r   )r   r   r8   r   )r   r5   r8   r   )r   r5   r8   r9   )r8   r   )r   r   r8   r   )r8   r   )r8   r   )r   r   r8   r   )r   )r   r   r8   r   )r8   r   )r8   r/   )r8   r   )r  r   r8   r   )r  r   r8   r   )r8   r(   )r   r5   r
  r   r8   r9   )r   r5   r
  r   r8   r   )r   r5   r8   r   )r   r   r8   r   )r8   r   )r8   rF  )rK  rL  r8   r9   )r8   r   )1rC  
__module____qualname____doc__r   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rw   propertyr   r  r  r  r   r   r  r  r   r   r   r"  r!  r   r   rE  rJ  rN  rP  rA   rA   rA   rB   rD   h   s    

l
'
)P&$H














	
C





!

D
	

,


:
	

rD   c                   @  s   e Zd ZdZdddZdS )r   z.An error with context for SDAM error handling.r  BaseExceptionr  r   r  r  r9   r  Optional[ObjectId]c                 C  s"   || _ || _|| _|| _|| _d S rO   )r  r  r  r  r  )r}   r  r  r  r  r  rA   rA   rB   r   9  s
   
z_ErrorContext.__init__N)
r  rU  r  r   r  r   r  r9   r  rV  )rC  rQ  rR  rS  r   rA   rA   rA   rB   r   6  s    r   
current_tvr   r  c                 C  s8   | du s|du r
dS | d |d krdS | d |d kS )z9Return True if the error's topologyVersion is <= current.NF	processIdcounterrA   )rW  r  rA   rA   rB   r  H  s
   r  
current_sdr'   new_sdc                 C  sF   | j |j }}|du s|du rdS |d |d krdS |d |d kS )z4Return True if the new topologyVersion is < current.NFrX  rY  )r  )rZ  r[  rW  Znew_tvrA   rA   rB   r   S  s   r   
candidatesr   r   r   c                   s"    s| S  fdd| D }|p| S )zBFilter out deprioritized servers from a list of server candidates.c                   s   g | ]}| vr|qS rA   rA   r3  r   rA   rB   r   d  s    z#_filter_servers.<locals>.<listcomp>rA   )r\  r   filteredrA   r]  rB   r   ]  s   r   )r6   r7   r8   r9   )rW  r   r  r   r8   r9   )rZ  r'   r[  r'   r8   r9   rO   )r\  r   r   r   r8   r   )\rS  
__future__r   r<  r^   r   r;   r   r   r   r   ru   pathlibr   typingr   r   r   r   r   r	   Zpymongor
   r   r   r   Z#pymongo.asynchronous.client_sessionr   r   Zpymongo.asynchronous.monitorr   r   Zpymongo.asynchronous.poolr   Zpymongo.asynchronous.serverr   Zpymongo.errorsr   r   r   r   r   r   r   r   r   Zpymongo.hellor   Zpymongo.lockr   r   r    Zpymongo.loggerr!   r"   r#   r$   r%   Zpymongo.pool_optionsr&   Zpymongo.server_descriptionr'   Zpymongo.server_selectorsr(   r)   r*   r+   r,   Zpymongo.topology_descriptionr-   r.   r/   r0   r1   Zbsonr2   Zpymongo.asynchronous.settingsr3   Zpymongo.typingsr4   r5   rn   r   __file__parentr   rC   rD   r   r  r   r   rA   rA   rA   rB   <module>   s\    ,
       U

