
    [j                       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	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mZmZmZmZmZm Z m!Z! ddl"m#Z# dd	l$m%Z% dd
l&m'Z' ddl(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8m9Z9m:Z:m;Z; e
rddl<m=Z= ddl>m?Z? ddl@mAZAmBZB d$dZC G d d          ZD G d d          ZEd%dZFd&d#ZGdS )'z<Internal class to monitor a topology of one or more servers.    )annotationsN)TYPE_CHECKINGAnyCallableMappingOptionalcast)_csotcommonhelpersperiodic_executor)_ServerSession_ServerSessionPool)	ConfigurationErrorConnectionFailureInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailurePyMongoErrorServerSelectionTimeoutError
WriteError)Hello)_create_lock)
SrvMonitor)PoolPoolOptions)Server)ServerDescription)	Selectionany_server_selectorarbiter_server_selectorreadable_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_Address	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)r/   qeventfnargss        T/var/www/app.qaans.com/backend/venv/lib/python3.11/site-packages/pymongo/topology.pyprocess_events_queuer<   D   sy    	A u	LLNNE HBBIII	 { 	 	 	E	 4s   0 AAc                     e Zd ZdZd]dZd^dZd_d	Z	 	 d`dadZdbdZ	 	 d`dcdZ		 	 d`dcdZ
	 dddedZ	 dfdgd!Zdfdgd"Zdhd%Zdhd&Zdid(Zdjd)Zdkd*Zdld,Zdmd-Zdmd.Zdnd0Zdod3Zdod4Zdpdqd8Zdrd9Zd^d:Zd^d;Zedsd=            Zdtd?Zd^d@Z d_dAZ!dudCZ"dvdFZ#dwdHZ$d^dIZ%dxdLZ&dydMZ'dydNZ(d^dOZ)d^dPZ*dzdRZ+dzdSZ,d{dUZ-d|dVZ.d}dXZ/d~d[Z0dd\Z1d
S )Topologyz*Monitor a topology of one or more servers.topology_settingsr,   c                $   |j         | _         |j        j        | _        | j        d uo| j        j        | _        | j        d uo| j        j        | _        d | _        d | _	        | j        s| j        rt          j        d          | _        | j        r5| j        J | j                            | j        j        | j         ff           || _        t          |                                |                                |j        d d |          }|| _        | j        r_| j        J t          t(          j        i d d d | j                  }| j                            | j        j        || j        | j         ff           |j        D ]?}| j        r6| j        J | j                            | j        j        || j         ff           @t3          |                                          | _        d| _        d| _        t=                      | _        | j                             | j                  | _!        i | _"        d | _#        d | _$        tK                      | _&        | j        s| j        ru| j        J d	fd}tO          j(        tR          j*        tR          j+        |d          }tY          j-        | j        |j.                  || _	        |/                                 d | _0        | j        j1        (| j        j2        stg          | | j                  | _0        d S d S d S )
Nd   )maxsizeFr1   r2   c                 "    t                     S N)r<   )weaks   r;   targetz!Topology.__init__.<locals>.target   s    +D111    pymongo_events_thread)intervalmin_intervalrF   name)r1   r2   )4_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr5   Queueputpublish_topology_opened	_settingsr(   get_topology_typeget_server_descriptionsreplica_set_name_descriptionr'   Unknown$publish_topology_description_changedseedspublish_server_openedlistserver_descriptions_seed_addresses_opened_closedr   _lockcondition_class
_condition_servers_pid_max_cluster_timer   _session_poolr   PeriodicExecutorr   EVENTS_QUEUE_FREQUENCYMIN_HEARTBEAT_INTERVALweakrefrefcloseopen_srv_monitorfqdnload_balancedr   )selfr?   topology_description
initial_tdseedrF   executorrE   s          @r;   __init__zTopology.__init__X   s4   -:+9J#d:at?a?$6_4?;_ &* 	44#3 	4 ;s333DL 	^<+++LdoEHYG[\]]]*2//115577. 
  
 1 
	<+++,%r4tT^ J LOH!2D4EF   &+ 	e 	eD# e|///  $/"G$PTPaIb!cddd  $$8$L$L$N$NOO!^^
.88DD02#'	8</11 	4#3 	<+++2 2 2 2 2 2 )96#:,	  H ;t|X^<<D%-D"MMOOO >*4>3O* *4 @ @D +***rG   r1   Nonec                   t          j                    }| j        || _        n|| j        k    r|| _        t          j        dd           | j        5  | j                                        D ]}|                                 | j	        
                                 ddd           n# 1 swxY w Y   | j        5  |                                  ddd           dS # 1 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, MongoClient must be created after any
          forking.

        NzMongoClient opened before fork. May not be entirely fork-safe, proceed with caution. See PyMongo's documentation for details: https://pymongo.readthedocs.io/en/stable/faq.html#is-pymongo-fork-safe   )
stacklevel)osgetpidrk   warningswarnrg   rj   valuesrs   rm   reset_ensure_opened)rx   pidservers      r;   rt   zTopology.open   sy    ikk9DIIDIDIM'      + +"m2244 # #FLLNNNN "((***+ + + + + + + + + + + + + + + Z 	" 	"!!!	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"s%   A
B((B,/B,:CC #C floatc                H    t          j                    }|| j        j        S |S rD   )r
   	remainingrY   server_selection_timeout)rx   timeouts     r;   get_server_selection_timeoutz%Topology.get_server_selection_timeout   s$    /##?>::rG   Nselector Callable[[Selection], Selection]r   Optional[float]addressOptional[_Address]list[Server]c                     |                                  }n|} j        5                       |||          } fd|D             cddd           S # 1 swxY w Y   dS )aL  Return a list of Servers matching selector, or time out.

        :Parameters:
          - `selector`: function that takes a list of Servers and returns
            a subset of them.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
          - `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sdrx   s     r;   
<listcomp>z+Topology.select_servers.<locals>.<listcomp>   s@       IKVT77
CCDD  rG   )r   rg   _select_servers_loop)rx   r   r   r   server_timeoutrc   s   `     r;   select_serverszTopology.select_servers   s    * $+!>>@@NN5NZ 	 	"&";";HnV]"^"^   Ob  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   %AAAr   list[ServerDescription]c                r   t          j                    }||z   }| j                            ||| j        j                  }|s|dk    s||k    r/t          |                     |           d| d| j                  | 	                                 | 
                                 | j                            t          j                   | j                                         t          j                    }| j                            ||| j        j                  }|| j                                         |S )z7select_servers() guts. Hold the lock when calling this.)custom_selectorr   z, Timeout: zs, Topology Description: )time	monotonicr]   apply_selectorrY   server_selectorr   _error_messagedescriptionr   _request_check_allri   waitr   rp   check_compatible)rx   r   r   r   nowend_timerc   s          r;   r   zTopology._select_servers_loop   sQ    n="/>>gt~/M ? 
 
 & 	!||sX~~1**844wwwwcgcsww   !!!##%%% O  !>???..000.""C"&"3"B"B'4>3Q #C # ## & 	* 	**,,,""rG   r   c                    |                      |||          }t          |          dk    r|d         S t          j        |d          \  }}|j        j        |j        j        k    r|S |S )N   r   r   )r   lenrandomsamplepooloperation_count)rx   r   r   r   serversserver1server2s          r;   _select_serverzTopology._select_server  sl     %%h0H'RRw<<11:!=!44<'7<+GGGNNrG   c                    |                      |||          }t          j                    rt          j        |j        j                   |S )zALike select_servers, but choose a random server if several match.)r   r
   get_timeoutset_rttr   min_round_trip_time)rx   r   r   r   r   s        r;   select_serverzTopology.select_server'  sI     $$X/GQQ 	BM&,@AAArG   r.   Optional[int]c                :    |                      t          ||          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.

        :Parameters:
          - `address`: A (host, port) pair.
          - `server_selection_timeout` (optional): maximum seconds to wait.
            If not provided, the default value
            common.SERVER_SELECTION_TIMEOUT is used.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        )r   r!   )rx   r   r   s      r;   select_server_by_addressz!Topology.select_server_by_address3  s    ( !!"57OQXYYYrG   Fserver_descriptionr   
reset_poolr2   c                "   | j         }|j        |j                 }t          ||          rdS t	          | j         |          }|j        s|j        rO|j        t          j	        k    r:| j
                            |j                  }|r|j                                         | j        s| j        o||k    }| j        r?|s=| j        J | j                            | j        j        |||j        | j        ff           || _         |                                  |                     |j                   | j        r>|s<| j        J | j                            | j        j        || j         | j        ff           | j        rA|j        t          j        k    r,| j         j        t6          vr| j                                         |r:| j
                            |j                  }|r|j                                         | j                                         dS )ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        N) r]   _server_descriptionsr   _is_stale_server_descriptionr*   is_readableis_server_type_knowntopology_typer'   Singlerj   getr   readyrQ   rS   rT   rW   rO   "publish_server_description_changedrL   _update_servers_receive_cluster_time_no_lockcluster_timer_   ru   r^   r&   rs   r   ri   
notify_all)rx   r   r   td_oldsd_oldnew_tdr   suppress_events           r;   _process_changezTopology._process_changeI  sF    ",-?-GH'0BCC 	F-d.?ASTT) 	$3	$8>8LP]Pd8d8d]&&'9'ABBF $!!###.B$2BdRdHd 	 	<+++LOF/1C1KTM^_   #**+=+JKKK 	N 	<+++LOHT.0AB    	& M$999!/7MMM##%%%  	$]&&'9'ABBF $!!### 	""$$$$$rG   c                    | j         5  | j        r5| j                            |j                  r|                     ||           ddd           dS # 1 swxY w Y   dS )z>Process a new ServerDescription after an hello call completes.N)rg   re   r]   
has_serverr   r   )rx   r   r   s      r;   	on_changezTopology.on_change  s     Z 
	E 
	E | E 1 < <=O=W X X E$$%7DDD
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	E 
	Es   =AAAseedlistlist[tuple[str, Any]]c                   | j         }|j        t          vrdS t          | j         |          | _         |                                  | j        r>| j        J | j                            | j        j	        || j         | j
        ff           dS dS )z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        N)r]   r   r&   r)   r   rS   rT   rW   rO   r_   rL   )rx   r   r   s      r;   _process_srv_updatezTopology._process_srv_update  s     "'===FEdFWYabb 	<+++LOHT.0AB    	 	rG   c                ~    | j         5  | j        r|                     |           ddd           dS # 1 swxY w Y   dS )z?Process a new list of nodes obtained from scanning SRV records.N)rg   re   r   )rx   r   s     r;   on_srv_updatezTopology.on_srv_update  s     Z 	3 	3| 3((222	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3s   266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.
        )rj   r   rx   r   s     r;   r   zTopology.get_server_by_address  s     }  )))rG   c                    || j         v S rD   )rj   r   s     r;   r   zTopology.has_server  s    $-''rG   c                    | j         5  | j        j        }|t          j        k    r	 ddd           dS t          |                                           d         j        cddd           S # 1 swxY w Y   dS )z!Return primary's address or None.Nr   )rg   r]   r   r'   ReplicaSetWithPrimaryr%   _new_selectionr   )rx   r   s     r;   get_primaryzTopology.get_primary  s     Z 	N 	N -;M CCC	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s   A++A++A/2A/set[_Address]c                ,   | j         5  | j        j        }|t          j        t          j        fvrt                      cddd           S d t           ||                                                     D             cddd           S # 1 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     r;   	<setcomp>z4Topology._get_replica_set_members.<locals>.<setcomp>  s    OOO2BJOOOrG   )	rg   r]   r   r'   r   ReplicaSetNoPrimarysetiterr   )rx   r   r   s      r;   _get_replica_set_membersz!Topology._get_replica_set_members  s    Z 	P 	P -;M31%   uu	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s   4B		3B		BBc                6    |                      t                    S )z"Return set of secondary addresses.)r   r$   rx   s    r;   get_secondarieszTopology.get_secondaries  s    ,,-FGGGrG   c                6    |                      t                    S )z Return set of arbiter addresses.)r   r"   r   s    r;   get_arbiterszTopology.get_arbiters  s    ,,-DEEErG   Optional[ClusterTime]c                    | j         S )z1Return a document, the highest seen $clusterTime.rl   r   s    r;   max_cluster_timezTopology.max_cluster_time  s    %%rG   r   Optional[Mapping[str, Any]]c                \    |r'| j         r|d         | j         d         k    r|| _         d S d S d S )NclusterTimer   rx   r   s     r;   r   z&Topology._receive_cluster_time_no_lock  sR      	6 *6.1G1VVV)5&&&	6 	6 WVrG   c                p    | j         5  |                     |           d d d            d S # 1 swxY w Y   d S rD   )rg   r   r   s     r;   receive_cluster_timezTopology.receive_cluster_time  s    Z 	= 	=..|<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	=s   +//   	wait_timeintc                    | j         5  |                                  | j                            |           ddd           dS # 1 swxY w Y   dS )z=Wake all monitors, wait for at least one to check its server.N)rg   r   ri   r   )rx   r   s     r;   request_check_allzTopology.request_check_all  s    Z 	, 	,##%%%O  +++	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,s   /A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.
        )r]   r   r'   r   known_serversreadable_serversr   s    r;   data_bearing_serverszTopology.data_bearing_servers  s0    
 *m.BBB$22 11rG   c           	        g }| j         5  |                                 D ]G}| j        |j                 }|                    ||j        j                                        f           H	 d d d            n# 1 swxY w Y   |D ]f\  }}	 |j                            |           !# t          $ r9}t          |d|dd           }|                     |j        j        |            d }~ww xY wd S )Nr   F)rg   r  rj   r   appendr   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )rx   r   r   r   
generationexcctxs          r;   update_poolzTopology.update_pool  sa   Z 	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 #* 	 	FJ00<<<<   #CJtDD!!&"4"<cBBB	 	s*   AA44A8;A8B""
C%,4C  C%c                   | j         5  | j                                        D ]}|                                 | j                                        | _        | j                                                                        D ] \  }}|| j        v r|| j        |         _        !| j	        r| j	                                         d| _
        d| _        ddd           n# 1 swxY w Y   | j        r5| j        J | j                            | j        j        | j        ff           | j        s| j        r| j                                         dS dS )zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        FTN)rg   rj   r   rs   r]   r   rc   itemsr   ru   re   rf   rS   rT   rW   rO   publish_topology_closedrL   rQ   rU   )rx   r   r   r   s       r;   rs   zTopology.close  s   
 Z 	  	 -..00   !% 1 7 7 9 9D#0DDFFLLNN < <dm++9;DM'*6   *!''))) DLDL	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 $  	^<+++LdoEHYG[\]]] 	+4#3 	+"((*****	+ 	+s   C	CC!$C!r(   c                    | j         S rD   )r]   r   s    r;   r   zTopology.description2  s      rG   list[_ServerSession]c                v    | j         5  | j                                        cddd           S # 1 swxY w Y   dS )z"Pop all session ids from the pool.N)rg   rm   pop_allr   s    r;   pop_all_sessionszTopology.pop_all_sessions6  s    Z 	0 	0%--//	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0s   .22c                n    | j         5  |                                  d d d            d S # 1 swxY w Y   d S rD   )rg   _check_session_supportr   s    r;   _check_implicit_session_supportz(Topology._check_implicit_session_support;  s    Z 	* 	*'')))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   *..c                   | j         j        rt          d          S | j        j        }|| j        j        t          j        k    r;| j        j        s.| 	                    t          |                                 d           n:| j        j        s.| 	                    t          |                                 d           | j        j        }|t          d          |S )z/Internal check for session support on clusters.infNz5Sessions are not supported by this MongoDB deployment)rY   rw   r   r]   logical_session_timeout_minutesr   r'   r   has_known_serversr   r!   r   r  r#   r   rx   session_timeouts     r;   r  zTopology._check_session_support?  s    >' 	 <<+K" .-2FFF(: --+T-N-N-P-PRV   &7 )),d.O.O.Q.QSW   #/OO&()`aaarG   r   c                    | j         5  |                                 }| j                            |          cddd           S # 1 swxY w Y   dS )z>Start or resume a server session, or raise ConfigurationError.N)rg   r  rm   get_server_sessionr"  s     r;   r%  zTopology.get_server_sessionV  s    Z 	J 	J"99;;O%88II	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	Js   .AA
Aserver_sessionlockc                    |rG| j         5  | j                            || j        j                   d d d            d S # 1 swxY w Y   d S | j                            |           d S rD   )rg   rm   return_server_sessionr]   r   return_server_session_no_lock)rx   r&  r'  s      r;   r)  zTopology.return_server_session\  s     	M  "88"D$5$U                    <<^LLLLLs   &=AAr    c                4    t          j        | j                  S )zmA Selection object, initially including all known servers.

        Hold the lock when calling this.
        )r    from_topology_descriptionr]   r   s    r;   r   zTopology._new_selectionf  s    
 243DEEErG   c                *   | j         rt          d          | j        sd| _        |                                  | j        s| j        r| j                                         | j        r,| j	        j
        t          v r| j                                         | j        j        rD|                     t          | j        d         t#          d| j        dd                               | j                                        D ]}|                                 dS )z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z"Cannot use MongoClient after closeTr   r      )ok	serviceIdmaxWireVersionN)rf   r   re   r   rS   rQ   rU   rt   ru   r   r   r&   rY   rw   r   r   rd   r   rL   rj   r   rx   r   s     r;   r   zTopology._ensure_openedm  s.   
 < 	I"#GHHH| 	DL  """  .4#7 .&++---   )d&6&DH^&^&^!&&(((~+ $$%,Q/QT5FZ\]]^^    m**,, 	 	FKKMMMM	 	rG   err_ctxr  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)rj   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancer5  dict _is_stale_error_topology_version)rx   r   r3  r   cur_tvr<  error_tvs          r;   _is_stale_errorzTopology._is_stale_error  s    ""7++>4<(()@'BTUU 	4 #4 	@WUI.. 	@%-.. @ =,,->??/AAArG   c                h   |                      ||          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          r t          |d          r|j        }n4t          |t                    rdnd }|j                            d|          }|t           j        v rv|t           j        v }| j        j        s$|                     t)          ||                     |s|j        dk    r|                    |           |                                 d S |j        sG| j        j        s$|                     t)          ||                     |                    |           d S d S t          |t0                    r`| j        j        s$|                     t)          ||                     |                    |           |j                                         d S d S )Ncodei{'  r<     )rC  rj   r<  r:  rY   rw   completed_handshaker>  r   r   r   r   r=  rE  r5  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r   max_wire_versionr   request_checkr   _monitorcancel_check)	rx   r   r3  r   r<  r:  err_codedefaultis_shutting_downs	            r;   _handle_errorzTopology._handle_error  sf   11 	Fw''
 >' 	
 	7C^ 	Fe^,, 1	+1L 1	+
 Fz** +	+F1ABCC (	+ uf%% > : $.e_#E#EO%%4 =,,VW==7555#+w/F#F ~3 R(():7%)P)P)PQQQ# -(@A(E(ELL,,,$$&&&&&0 )~3 R(():7%)P)P)PQQQZ((((() ) 011 
	+ >/ N$$%6we%L%L%LMMMLL$$$ O((*****
	+ 
	+rG   c                r    | j         5  |                     ||           ddd           dS # 1 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)rg   rR  )rx   r   r3  s      r;   r  zTopology.handle_error  s     Z 	1 	1w000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1s   ,00c                f    | j                                         D ]}|                                 dS )z3Wake all monitors. Hold the lock when calling this.N)rj   r   rL  r2  s     r;   r   zTopology._request_check_all  s>    m**,, 	# 	#F  """"	# 	#rG   c           	        | j                                                                         D ]\  }}|| j        vr| j                            || |                     |          | j                  }d}| j        r | j        t          j
        | j                  }t          ||                     |          || j        | j        |          }|| j        |<   |                                 | j        |         j        j        }|| j        |         _        ||j        k    r*| j        |         j                            |j                   t)          | j                                                  D ]M\  }}| j                             |          s.|                                 | j                            |           NdS )zrSync our Servers from TopologyDescription.server_descriptions.

        Hold the lock while calling this.
        )r   topologyr   r?   N)r   r   monitortopology_id	listenersevents)r]   rc   r  rj   rY   monitor_class_create_pool_for_monitorrQ   rT   rq   rr   r   _create_pool_for_serverrL   rO   rt   r   is_writabler   update_is_writablerb   r   rs   pop)rx   r   r   rW  rE   r   was_writables          r;   r   zTopology._update_servers  s   
  ,@@BBHHJJ 	S 	SKGRdm++.66')!66w??&*n	 7   ' 5DL,D";t|44D')55g>># $ 1"o   *0g&  $}W5AM57g&22>11M'*/BB2>RRR#DM$7$7$9$9:: 	+ 	+OGV$//88 +!!'***	+ 	+rG   r   c                L    | j                             || j         j                  S rD   )rY   
pool_classpool_optionsr   s     r;   r]  z Topology._create_pool_for_server  s    ~(($.2MNNNrG   c                    | j         j        }t          |j        |j        |j        |j        |j        |j        |j        d|j	        	  	        }| j         
                    ||d          S )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshake)rY   rd  r   rf  _ssl_contextri  rN   rk  rl  rn  rc  )rx   r   optionsmonitor_pool_optionss       r;   r\  z!Topology._create_pool_for_monitor  su    .-
  +#3"2,(/(K#4O>)
 
 
 
 
 
 ~((2FRW(XXXrG   strc                   | 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 rD   rF  )r   r   r<  s     r;   	<genexpr>z*Topology._error_message.<locals>.<genexpr>\  s*      GGv|u,GGGGGGrG   r   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 rD   )r<  rs  )r   r   s     r;   rx  z*Topology._error_message.<locals>.<genexpr>k  s3      XXf6<XFL 1 1XXXXXXrG   )r]   r   r'   r   r   Shardedr  r%   rb   rc   r   formatrY   r\   r<  allr   intersectionrd   rs  join)rx   r   is_replica_setserver_plural	addressesr   samer<  s          @r;   r   zTopology._error_message3  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XrG   c                L    d}| j         sd}d| j        j         d| | j        dS )N zCLOSED < >)re   	__class____name__r]   )rx   msgs     r;   __repr__zTopology.__repr__m  s<    | 	CH4>*HHSH$2CHHHHrG   >tuple[tuple[_Address, ...], Optional[str], Optional[str], str]c                x    | j         }t          t          |j                            |j        |j        |j        fS )z?The properties to use for MongoClient/Topology equality checks.)rY   tuplesortedr`   r\   rv   srv_service_name)rx   tss     r;   eq_propszTopology.eq_propss  s2    ^fRX&&'')<bgrGZ[[rG   otherobjectc                    t          || j                  r*|                                 |                                k    S t          S rD   )r>  r  r  NotImplemented)rx   r  s     r;   __eq__zTopology.__eq__x  s9    eT^,, 	7==??enn&6&666rG   c                D    t          |                                           S rD   )hashr  r   s    r;   __hash__zTopology.__hash__}  s    DMMOO$$$rG   )r?   r,   )r1   r~   )r1   r   )NN)r   r   r   r   r   r   r1   r   )r   r   r   r   r   r   r1   r   )r   r   r   r   r   r   r1   r   rD   )r   r.   r   r   r1   r   )F)r   r   r   r2   r1   r~   )r   r   r1   r~   )r   r.   r1   r   )r   r.   r1   r2   )r1   r   )r   r   r1   r   )r1   r   )r1   r   )r   r   r1   r~   )r   )r   r  r1   r~   )r1   r   )r1   r(   )r1   r  )r1   r   )r&  r   r'  r2   r1   r~   )r1   r    )r   r.   r3  r  r1   r2   )r   r.   r3  r  r1   r~   )r   r.   r1   r   )r   r   r1   rs  )r1   rs  )r1   r  )r  r  r1   r2   )r1   r  )2r  
__module____qualname____doc__r}   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  rs   propertyr   r  r  r  r%  r)  r   r   rC  rR  r  r   r   r]  r\  r   r  r  r  r  r   rG   r;   r>   r>   U   sF       44NA NA NA NA`!" !" !" !"F    59&*	    B## ## ## ##P 59&*	    $ 59&*	
 
 
 
 
 LPZ Z Z Z Z. IN=% =% =% =% =%~E E E E E   (3 3 3 3* * * *( ( ( (N N N NP P P PH H H HF F F F& & & &6 6 6 6= = = =, , , , ,2 2 2 2   "+ + + +: ! ! ! X!0 0 0 0
* * * *   .J J J JM M M MF F F F   BB B B B(@+ @+ @+ @+D1 1 1 1# # # #
(+ (+ (+ (+TO O O OY Y Y Y(8Y 8Y 8Y 8YtI I I I\ \ \ \
   
% % % % % %rG   r>   c                      e Zd ZdZddZdS )r  z.An error with context for SDAM error handling.r<  BaseExceptionrK  r  r9  rH  r2   r:  Optional[ObjectId]c                L    || _         || _        || _        || _        || _        d S rD   )r<  rK  r9  rH  r:  )rx   r<  rK  r9  rH  r:  s         r;   r}   z_ErrorContext.__init__  s.     
 0.#6 $rG   N)
r<  r  rK  r  r9  r  rH  r2   r:  r  )r  r  r  r  r}   r   rG   r;   r  r    s.        88% % % % % %rG   r  
current_tvr   rB  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  rB  s     r;   r@  r@    sC     X-u+(;"777ui HY$777rG   
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  )r;  )r  r  r  new_tvs       r;   r   r     sO    #4f6MJV^u+&"555ui 6)#444rG   )r/   r0   r1   r2   )r  r   rB  r   r1   r2   )r  r   r  r   r1   r2   )Hr  
__future__r   r   r5   r   r   r   rq   typingr   r   r   r   r   r	   pymongor
   r   r   r   pymongo.client_sessionr   r   pymongo.errorsr   r   r   r   r   r   r   r   r   pymongo.hellor   pymongo.lockr   pymongo.monitorr   pymongo.poolr   r   pymongo.serverr   pymongo.server_descriptionr   pymongo.server_selectorsr    r!   r"   r#   r$   r%   pymongo.topology_descriptionr&   r'   r(   r)   r*   bsonr+   pymongo.settingsr,   pymongo.typingsr-   r.   r<   r>   r  r@  r   r   rG   r;   <module>r     s   C B " " " " " " 				      H H H H H H H H H H H H H H H H = = = = = = = = = = = = E E E E E E E E
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        % % % % % % & & & & & & * * * * * * * * ! ! ! ! ! ! 8 8 8 8 8 8                              611111155555555   "i% i% i% i% i% i% i% i%X% % % % % % % %$8 8 8 85 5 5 5 5 5rG   