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   Y/var/www/html/olx_land/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   previousDescriptionnewDescriptionr      )rI   rJ   
serverHost
serverPortFr8   r9   c                     s
   t  S N)rC   rA   weakrA   rB   target   s   z!Topology.__init__.<locals>.targetpymongo_events_thread)intervalmin_intervalrT   name)r8   r9   )@_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	_settingsr/   get_topology_typeget_server_descriptionsreplica_set_name_descriptionr.   Unknown$publish_topology_description_changedTOPOLOGY_CHANGEseedspublish_server_openedSTART_SERVERlistserver_descriptions_seed_addresses_opened_closedr    _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)selfrE   topology_description
initial_tdseedrT   executorrA   rR   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   )      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warnrz   r~   valuesr   r   reset_ensure_opened)r   pidkwargsserverrA   rA   rB   r      s,   

(.zTopology.openfloatc                 C  s   t  }|d u r| jjS |S rQ   )r
   	remainingrj   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   r{   r   cleanup_monitorsrz   _select_servers_loop)r   r   r   r   r   r   server_timeoutrv   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)custom_selectorr   )rI   r   r   r   r   r   failurez, Timeout: zs, Topology Description: i  )rI   r   r   r   r   r   remainingTimeMSTN)time	monotonicr"   rd   re   rf   r#   r%   STARTEDdescription_topology_settingsrY   rn   apply_selectorrj   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_waitingrv   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 )NrN   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
r   r   r   r   r   r   r   serversserver1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   rN   )rI   r   r   r   r   r   rO   rP   )r   r
   get_timeoutset_rttr   min_round_trip_timer"   rd   re   rf   r#   r%   	SUCCEEDEDr   rY   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   )'rn   _server_descriptionsr   _is_stale_server_descriptionr1   is_readableis_server_type_knowntopology_typer.   Singler~   getr   readyr^   ra   rh   r\   "publish_server_description_changedrY   _update_serversr`   rp   r!   rd   re   rf   r#   r$   rq   r   ro   r-   r   r{   r   appendr}   
notify_all)	r   r   r   r   td_oldsd_oldnew_tdr   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   )
rz   rx   rn   
has_serverr   r   r~   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   )rn   r   r-   r0   r   r`   ra   rh   r\   rp   rY   r!   rd   re   rf   r#   r$   rq   )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)rz   rx   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.
        )r~   r   r   r   rA   rA   rB   r   S  s   zTopology.get_server_by_addressc                 C  s
   || j v S rQ   )r~   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   )rz   rn   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>)	rz   rn   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.r   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 )N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 rQ   )rz   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)rz   r   r   r}   )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.
        )rn   r   r.   r   known_servers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)rz   r%  r~   r   r   r   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )r   r   r   r   
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   rN   ),rz   rn   r~   r   r   r{   r   r   _monitorr   rv   itemsr   r   rx   ry   r`   ra   r/   r.   ro   rm   max_set_versionmax_election_idr   rh   r\   rp   rY   publish_topology_closedr!   rd   re   rf   r#   r$   rq   STOP_TOPOLOGYr^   rb   joinrC   r   r   )r   old_tdr   r   r   rA   rA   rB   r     sn   
(


zTopology.closer/   c                 C  r  rQ   )rn   r   rA   rA   rB   r     r  zTopology.descriptionlist[_ServerSession]c                 C  s
   | j  S )z"Pop all session ids from the pool.)r   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.)r   get_server_session)r   r:  rA   rA   rB   r;    s   zTopology.get_server_sessionserver_sessionc                 C  s   | j | d S rQ   )r   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(   from_topology_descriptionrn   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   rN      )ok	serviceIdmaxWireVersion)ry   r   rx   r   r`   r^   rb   r   r   r   r   r-   rj   r   r   r'   rw   r   rY   r~   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detailstopologyVersion)r~   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancerE  dict _is_stale_error_topology_version)r   r   rD  r   cur_tvrL  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{'  rL     )rS  r~   rL  rJ  rj   r   completed_handshakerN  r   r   r   r   rM  rT  rE  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r'   max_wire_versionr   request_checkr   r   r/  cancel_check)	r   r   rD  r   rL  rJ  err_codedefault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)rz   r`  )r   r   rD  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)r~   r   r[  rC  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   topologyr   rE   N)r   r   monitortopology_id	listenersevents)rn   rv   r0  r~   rj   monitor_class_create_pool_for_monitorr^   ra   r   r   r   _create_pool_for_serverrY   r\   r   r   is_writabler   update_is_writableru   r   r   r{   r   r   r/  pop)r   r   r   rb  rS   r   was_writablerA   rA   rB   r     sF   

	
zTopology._update_serversr   c                 C  s   | j j|| j j| jdS )N)	client_id)rj   
pool_classpool_optionsrY   r  rA   rA   rB   rh    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_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshakerm  )rj   ro  r&   rp  _ssl_contextrs  r[   ru  rv  rx  rn  rY   )r   r   optionsmonitor_pool_optionsrA   rA   rB   rg    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 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  s    | ]}|j  kV  qd S rQ   rU  r   r   rU  rA   rB   	<genexpr>  s    z*Topology._error_message.<locals>.<genexpr>rN   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 rQ   )rL  r   r  rA   rA   rB   r    s    )rn   r   r.   r  r  Shardedr#  r,   ru   rv   r   formatrj   rm   rL  allr  intersectionrw   r   r5  )r   r   is_replica_setserver_plural	addressesr   samerA   rU  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   )r5  )r   trA   rA   rB   r      s    z-Topology.cleanup_monitors.<locals>.<listcomp>return_exceptionsT)r   r   rk  
IndexErrorasyncio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 < >)rx   	__class____name__rn   )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.)rj   tuplesortedrr   rm   r   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 rQ   )rN  r  r  NotImplemented)r   r  rA   rA   rB   __eq__-  s   zTopology.__eq__c                 C  s   t |  S rQ   )hashr  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   r7  )r:  r   r8   r   )r<  r   r8   r   )r8   r(   )r   r5   rD  r)  r8   r9   )r   r5   rD  r)  r8   r   )r   r5   r8   r   )r   r   r8   r   )r8   r   )r8   r  )r  r  r8   r9   )r8   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   r9  r;  r=  r	  r   rS  r`  r*  r   r   rh  rg  r   r   r  r  r  r  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.rL  BaseExceptionrZ  r   rI  rW  r9   rJ  Optional[ObjectId]c                 C  s"   || _ || _|| _|| _|| _d S rQ   )rL  rZ  rI  rW  rJ  )r   rL  rZ  rI  rW  rJ  rA   rA   rB   r   9  s
   
z_ErrorContext.__init__N)
rL  r  rZ  r   rI  r   rW  r9   rJ  r  )r  r  r  r  r   rA   rA   rA   rB   r)  6  s    r)  
current_tvr  rR  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   )r  rR  rA   rA   rB   rP  H  s
   rP  
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.NFr  r  )rK  )r  r  r  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   r  r   rA   rB   r   d  s    z#_filter_servers.<locals>.<listcomp>rA   )r  r   filteredrA   r  rB   r   ]  s   r   )r6   r7   r8   r9   )r  r  rR  r  r8   r9   )r  r'   r  r'   r8   r9   rQ   )r  r   r   r   r8   r   )\r  
__future__r   r  re   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.   r/   r0   r1   bsonr2   pymongo.asynchronous.settingsr3   pymongo.typingsr4   r5   r{   r   __file__parentr   rC   rD   r)  rP  r   r   rA   rA   rA   rB   <module>   s\    ,
       U

