
    FCf                    *   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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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*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z?m@Z@mAZAmBZB erddlCmDZD ddlEmFZF ddlGmHZHmIZI  eJ eeK      j                        ZMddZN G d d      ZO G d d      ZP	 	 	 	 	 	 ddZQddZR	 d 	 	 	 	 	 d!dZSy)"z<Internal class to monitor a topology of one or more servers.    )annotationsN)Path)TYPE_CHECKINGAnyCallableMappingOptionalcast)_csotcommonhelpersperiodic_executor)_ServerSession_ServerSessionPool)ConnectionFailureInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailurePyMongoErrorServerSelectionTimeoutError
WriteError)Hello)_create_lock)_SERVER_SELECTION_LOGGER
_debug_log	_info_log_ServerSelectionStatusMessage)
SrvMonitor)PoolPoolOptions)Server)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_Addressc                     |        }|sy	 	 |j                         }|\  }} ||  # t        j                  $ r Y yw xY w)NFT)
get_nowaitqueueEmpty)	queue_refqeventfnargss        P/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/pymongo/topology.pyprocess_events_queuer<   N   sV    A
	LLNE HBI  {{ 	
 	s   ( >>c                  2   e Zd ZdZd.dZd/dZd0dZ	 	 	 d1	 	 	 	 	 	 	 	 	 	 	 d2dZ	 	 	 	 	 	 	 	 	 	 	 	 d3dZ	 	 	 	 d4	 	 	 	 	 	 	 	 	 	 	 	 	 d5dZ		 	 	 	 d4	 	 	 	 	 	 	 	 	 	 	 	 	 d5d	Z
	 	 d6	 	 	 	 	 	 	 	 	 d7d
Z	 	 d8	 	 	 	 	 	 	 d9dZ	 	 d8	 	 	 	 	 	 	 d9dZd:dZd:dZd;dZd<dZd=dZd>dZd?dZd?dZd@dZdAdZdAdZdBdCdZdDdZd/dZd/dZedEd       ZdFdZdGdZ dHdZ!dId Z"d/d!Z#dJd"Z$dKd#Z%dKd$Z&d/d%Z'd/d&Z(dLd'Z)dLd(Z*dMd)Z+dNd*Z,dOd+Z-dPd,Z.dQd-Z/y)RTopologyz*Monitor a topology of one or more servers.c                   |j                   | _         |j                  j                  | _        | j                  d uxr | j                  j                  | _        | j                  d uxr | j                  j                  | _        d | _        d | _	        | j
                  s| j                  rt        j                  d      | _        | j                  rJ| j                  J | j                  j                  | j                  j                  | j                   ff       || _        t        |j!                         |j#                         |j$                  d d |      }|| _        | j                  r~| j                  J t        t(        j*                  i d d d | j                        }| j                  j                  | j                  j,                  || j&                  | j                   ff       |j.                  D ]Z  }| j
                  s| j                  J | j                  j                  | j                  j0                  || j                   ff       \ t3        |j5                               | _        d| _        d| _        t=               | _        | j                  jA                  | j>                        | _!        i | _"        d | _#        d | _$        tK               | _&        | j
                  s| j                  r| j                  J dfd}tO        jP                  tR        jT                  tR        jV                  |d      }tY        jZ                  | j                  |j\                        || _	        |j_                          d | _0        | j                  jb                  3| j                  jd                  stg        | | j                        | _0        y y y )Nd   )maxsizeFc                     t               S N)r<   )weaks   r;   targetz!Topology.__init__.<locals>.target   s    +D11    pymongo_events_thread)intervalmin_intervalrE   name)returnbool)4_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr4   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   )selftopology_settingstopology_description
initial_tdseedrE   executorrD   s          @r;   __init__zTopology.__init__b   s   -::+99JJ#d:at?a?a??$6_4??;_;_ &*4#3#3 ;;s3DL<<+++LLdooEEHYHYG[\]*2//1557.. 
 1<<+++,%%r4tT^^J LLOOHH!2!2D4E4EF &++ 	eD##||///  $//"G"G$PTPaPaIb!cd	e  $$8$L$L$NO!^
..88D02#'	8</14#3#3<<+++2 )9966#::,	H ;;t||X^^<D%-D"MMO >>*4>>3O3O *4 @D 4P*rF   c                *   t        j                         }| j                  || _        n|| j                  k7  r|| _        t        j                  dd dk\  r
dt
        fi}nddi}t        j                  	 di | | j                  5  | j                  j                         D ]  }|j                           | j                  j                          ddd       | j                  5  | j                          ddd       y# 1 sw Y   /xY w# 1 sw Y   yxY w)a  Start monitoring, or restart after a fork.

        No effect if called multiple times.

        .. warning:: Topology is shared among multiple threads and is protected
          by mutual exclusion. Using Topology from a process other than the one
          that initialized it will emit a warning and may result in deadlock. To
          prevent this from happening, MongoClient must be created after any
          forking.

        N   )      skip_file_prefixes
stacklevel   )zMongoClient 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)osgetpidrl   sysversion_info_pymongo_dirwarningswarnrh   rk   valuesrt   rn   reset_ensure_opened)ry   pidkwargsservers       r;   ru   zTopology.open   s     iik99DIDIIDI#w..@&*MM'
   +"mm224 #FLLN# ""((*+ ZZ 	"!	" 	"+ +	" 	"s   A
C=#D	=D	Dc                ^    t        j                         }|| j                  j                  S |S rC   )r   	remainingrZ   server_selection_timeout)ry   timeouts     r;   get_server_selection_timeoutz%Topology.get_server_selection_timeout   s(    //#?>>:::rF   Nc           
        || j                         }n|}| j                  5  | j                  |||||      }|D cg c]+  }t        t        | j                  |j                              - c}cddd       S c c}w # 1 sw Y   yxY w)a  Return a list of Servers matching selector, or time out.

        :param selector: function that takes a list of Servers and returns
            a subset of them.
        :param operation: The name of the operation that the server is being selected for.
        :param server_selection_timeout: maximum seconds to wait.
            If not provided, the default value common.SERVER_SELECTION_TIMEOUT
            is used.
        :param address: optional server address to select.

        Calls self.open() if needed.

        Raises exc:`ServerSelectionTimeoutError` after
        `server_selection_timeout` if no matching servers are found.
        N)r   rh   _select_servers_loopr
   r"   get_server_by_addressaddress)	ry   selector	operationr   r   operation_idserver_timeoutrd   sds	            r;   select_serverszTopology.select_servers   s    . $+!>>@N5NZZ 	"&";";.)\7#
 PcIKVT77

CD	 	
	 	s   A=0A8,A=8A==Bc                Z   t        j                         }||z   }d}t        j                  t        j
                        rLt        t        t        j                  |||| j                  | j                  j                  j                         | j                  j                  ||| j                  j                        }	|	s|dk(  s||kD  rt        j                  t        j
                        r\t        t        t        j                   |||| j                  | j                  j                  j                  | j#                  |             t%        | j#                  |       d| d| j                        |smt'        t        t        j(                  |||| j                  | j                  j                  j                  t+        |t        j                         z
               d	}| j-                          | j/                          | j0                  j3                  t4        j6                         | j                  j9                          t        j                         }| j                  j                  ||| j                  j                        }	|	s| j                  j9                          |	S )
z7select_servers() guts. Hold the lock when calling this.F)messager   r   operationIdtopologyDescriptionclientId)custom_selectorr   )r   r   r   r   r   r   failurez, Timeout: zs, Topology Description: )r   r   r   r   r   r   remainingTimeMST)time	monotonicr   isEnabledForloggingDEBUGr   r   STARTEDdescription_topology_settingsrM   r^   apply_selectorrZ   server_selectorFAILED_error_messager   r   WAITINGintr   _request_check_allrj   waitr   rq   check_compatible)
ry   r   r   r   r   r   nowend_timelogged_waitingrd   s
             r;   r   zTopology._select_servers_loop  s9    nn=#00?(5==!#($($4$4))<<II #//>>gt~~/M/M ? 
 &!|sX~+88G0 = D D!)"+$0,0,<,<!%!1!1!D!D!Q!Q $ 3 3H =	 2**845[	Ibcgcscsbvw  ",9AA%' ,(,(8(8!--@@MM$'4>>3C(C$D	 "&!##% OO  !>!>?..0.."C"&"3"3"B"B'4>>3Q3Q #C #S &Z 	**,""rF   c                    | j                  |||||      }t        ||      }t        |      dk(  r|d   S t        j                  |d      \  }}	|j
                  j                  |	j
                  j                  k  r|S |	S )N   r   r   )r   _filter_serverslenrandomsamplepooloperation_count)
ry   r   r   r   r   deprioritized_serversr   serversserver1server2s
             r;   _select_serverzTopology._select_serverR  s     %%i!97L
 "'+@Aw<11:!==!4<<''7<<+G+GGNNrF   c                   | j                  ||||||      }t        j                         r)t        j                  |j                  j
                         t        j                  t        j                        r|t        t        t        j                  |||| j                  | j                  j                  j                  |j                  j                  d   |j                  j                  d   	       |S )zALike select_servers, but choose a random server if several match.r   r   r   )r   r   r   r   r   r   
serverHost
serverPort)r   r   get_timeoutset_rttr   min_round_trip_timer   r   r   r   r   r   	SUCCEEDEDr   rM   r   )ry   r   r   r   r   r   r   r   s           r;   select_serverzTopology.select_serverg  s     $$$!% % 
 MM&,,@@A#00?(5??!#($($4$4))<<II!--55a8!--55a8
 rF   c                6    | j                  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.

        :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   )r   r%   )ry   r   r   r   r   s        r;   select_server_by_addressz!Topology.select_server_by_address  s+    2 !!$% " 
 	
rF   c                4   | j                   }|j                  |j                     }t        ||      ryt	        | j                   |      }|j
                  s)|j                  r^|j                  t        j                  k(  rA| j                  j                  |j                        }|r|j                  j                          | j                  xs | j                  xr ||k(  }| j                  rY|sW| j                   J | j                   j#                  | j$                  j&                  |||j                  | j(                  ff       || _         | j+                          | j-                  |j.                         | j                  rX|sV| j                   J | j                   j#                  | j$                  j0                  || j                   | j(                  ff       | j2                  rS|j                  t        j4                  k(  r6| j                   j                  t6        vr| j2                  j9                          |rC| j                  j                  |j                        }|r|j                  j;                  |       | j<                  j?                          y)ziProcess a new ServerDescription on an opened topology.

        Hold the lock when calling this.
        N)interrupt_connections) r^   _server_descriptionsr   _is_stale_server_descriptionr-   is_readableis_server_type_knowntopology_typer*   Singlerk   getr   readyrR   rT   rU   rX   rP   "publish_server_description_changedrM   _update_servers_receive_cluster_time_no_lockcluster_timer`   rv   r_   r)   rt   r   rj   
notify_all)	ry   server_description
reset_poolr   td_oldsd_oldnew_tdr   suppress_events	            r;   _process_changezTopology._process_change  s&    "",,-?-G-GH'0BC-d.?.?AST))338L8LP]PdPd8d]]&&'9'A'ABF!!#..B$2B2BdRdHd<<+++LLOOFF/1C1K1KTM^M^_ #**+=+J+JKN<<+++LLOOHHT..0A0AB   M$9$99!!//7MM##% ]]&&'9'A'ABF!!8M!N 	""$rF   c                    | j                   5  | j                  r8| j                  j                  |j                        r| j                  |||       ddd       y# 1 sw Y   yxY w)z>Process a new ServerDescription after an hello call completes.N)rh   rf   r^   
has_serverr   r   )ry   r   r   r   s       r;   	on_changezTopology.on_change  s[     ZZ 
	\ || 1 1 < <=O=W=W X$$%7EZ[
	\ 
	\ 
	\s   AAA$c                ^   | j                   }|j                  t        vryt        | j                   |      | _         | j	                          | j
                  rW| j                  J | j                  j                  | j                  j                  || j                   | j                  ff       yy)z_Process a new seedlist on an opened topology.
        Hold the lock when calling this.
        N)r^   r   r)   r,   r   rT   rU   rX   rP   r`   rM   )ry   seedlistr   s      r;   _process_srv_updatezTopology._process_srv_update   s     ""'==EdFWFWYab<<+++LLOOHHT..0A0AB rF   c                    | j                   5  | j                  r| j                  |       ddd       y# 1 sw Y   yxY w)z?Process a new list of nodes obtained from scanning SRV records.N)rh   rf   r   )ry   r   s     r;   on_srv_updatezTopology.on_srv_update  s5     ZZ 	3||((2	3 	3 	3s   4=c                8    | j                   j                  |      S )aJ  Get a Server or None.

        Returns the current version of the server immediately, even if it's
        Unknown or absent from the topology. Only use this in unittests.
        In driver code, use select_server_by_address, since then you're
        assured a recent view of the server's type and wire protocol version.
        )rk   r   ry   r   s     r;   r   zTopology.get_server_by_address  s     }}  ))rF   c                    || j                   v S rC   )rk   r   s     r;   r   zTopology.has_server%  s    $--''rF   c                    | j                   5  | j                  j                  }|t        j                  k7  r
	 ddd       yt        | j                               d   j                  cddd       S # 1 sw Y   yxY w)z!Return primary's address or None.Nr   )rh   r^   r   r*   ReplicaSetWithPrimaryr(   _new_selectionr   )ry   r   s     r;   get_primaryzTopology.get_primary(  sp     ZZ 	N --;;M C CC	N 	N
 ,D,?,?,AB1EMM	N 	N 	Ns   +A0%A00A9c                T   | j                   5  | j                  j                  }|t        j                  t        j
                  fvrt               cddd       S t         || j                                     D ch c]  }|j                   c}cddd       S c c}w # 1 sw Y   yxY w)z+Return set of replica set member addresses.N)
rh   r^   r   r*   r   ReplicaSetNoPrimarysetiterr   r   )ry   r   r   r   s       r;   _get_replica_set_membersz!Topology._get_replica_set_members2  s     ZZ 	P --;;M3311%  u	P 	P *.ht7J7J7L.M)NO2BJJO	P 	P P	P 	Ps$   AB!B:BBBB'c                ,    | j                  t              S )z"Return set of secondary addresses.)r   r'   ry   s    r;   get_secondarieszTopology.get_secondaries?  s    ,,-FGGrF   c                ,    | j                  t              S )z Return set of arbiter addresses.)r   r&   r  s    r;   get_arbiterszTopology.get_arbitersC  s    ,,-DEErF   c                    | j                   S )z1Return a document, the highest seen $clusterTime.rm   r  s    r;   max_cluster_timezTopology.max_cluster_timeG  s    %%%rF   c                \    |r*| j                   r|d   | j                   d   kD  r|| _         y y y )NclusterTimer  ry   r   s     r;   r   z&Topology._receive_cluster_time_no_lockK  s=      **.1G1G1VV)5& W	 rF   c                h    | j                   5  | j                  |       d d d        y # 1 sw Y   y xY wrC   )rh   r   r  s     r;   receive_cluster_timezTopology.receive_cluster_timeZ  s,    ZZ 	=..|<	= 	= 	=s   (1c                    | j                   5  | j                          | j                  j                  |       ddd       y# 1 sw Y   yxY w)z=Wake all monitors, wait for at least one to check its server.N)rh   r   rj   r   )ry   	wait_times     r;   request_check_allzTopology.request_check_all^  s<    ZZ 	,##%OO  +	, 	, 	,s   ,AAc                    | j                   j                  t        j                  k(  r| j                   j                  S | j                   j
                  S )z~Return a list of all data-bearing servers.

        This includes any server that might be selected for an operation.
        )r^   r   r*   r   known_serversreadable_serversr  s    r;   data_bearing_serverszTopology.data_bearing_serversd  sB    
 **m.B.BB$$222  111rF   c           	        g }| j                   5  | j                         D ]P  }| j                  |j                     }|j	                  ||j
                  j                  j                         f       R 	 d d d        |D ]!  \  }}	 |j
                  j                  |       # y # 1 sw Y   0xY w# t        $ r;}t        |d|dd       }| j                  |j                  j                  |        d }~ww xY w)Nr   F)rh   r  rk   r   appendr   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )ry   r   r   r   
generationexcctxs          r;   update_poolzTopology.update_poolm  s    ZZ 	H//1 Hrzz2(C(C(EFGH	H #* 	FJ00<		H 	H   #CJtD!!&"4"4"<"<cBs$   A$B#B/#B,/	C386C..C3c                   | j                   5  | j                  j                         D ]  }|j                           | j                  j                         | _        | j                  j                         j                         D ](  \  }}|| j                  v s|| j                  |   _        * | j                  r| j                  j                          d| _
        d| _        ddd       | j                  rJ| j                  J | j                  j                  | j                  j                   | j"                  ff       | j$                  s| j                  r| j&                  j                          yy# 1 sw Y   xY w)zClear pools and terminate monitors. Topology does not reopen on
        demand. Any further operations will raise
        :exc:`~.errors.InvalidOperation`.
        FTN)rh   rk   r   rt   r^   r   rd   itemsr   rv   rf   rg   rT   rU   rX   rP   publish_topology_closedrM   rR   rV   )ry   r   r   r   s       r;   rt   zTopology.close~  s>   
 ZZ 	 --..0  !% 1 1 7 7 9D#00DDFLLN <dmm+9;DMM'*6<
   !!'') DLDL	 $ <<+++LLdooEEHYHYG[\]4#3#3""((* $4+	  	 s   BE5A
E55E>c                    | j                   S rC   )r^   r  s    r;   r   zTopology.description  s       rF   c                z    | j                   5  | j                  j                         cddd       S # 1 sw Y   yxY w)z"Pop all session ids from the pool.N)rh   rn   pop_allr  s    r;   pop_all_sessionszTopology.pop_all_sessions  s0    ZZ 	0%%--/	0 	0 	0s   1:c                |    | j                   5  | j                  j                  |      cddd       S # 1 sw Y   yxY w)z>Start or resume a server session, or raise ConfigurationError.N)rh   rn   get_server_session)ry   session_timeout_minutess     r;   r(  zTopology.get_server_session  s7    ZZ 	R%%889PQ	R 	R 	Rs   2;c                    |rF| j                   5  | j                  j                  || j                  j                         d d d        y | j                  j                  |       y # 1 sw Y   y xY wrC   )rh   rn   return_server_sessionr^   logical_session_timeout_minutesreturn_server_session_no_lock)ry   server_sessionlocks      r;   r+  zTopology.return_server_session  sa     ""88"D$5$5$U$U  <<^L s   1A%%A.c                @    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_selection  s    
 2243D3DEErF   c                h   | j                   rt        d      | j                  sd| _        | j                          | j                  s| j
                  r| j                  j                          | j                  r6| j                  j                  t        v r| j                  j                          | j                  j                  r?| j                  t        | j                   d   t#        d| j$                  dd                   | j&                  j)                         D ]  }|j                           y)z[Start monitors, or restart after a fork.

        Hold the lock when calling this.
        z"Cannot use MongoClient after closeTr   r      )ok	serviceIdmaxWireVersionN)rg   r   rf   r   rT   rR   rV   ru   rv   r   r   r)   rZ   rx   r   r#   re   r   rM   rk   r   ry   r   s     r;   r   zTopology._ensure_opened  s    
 <<"#GHH||DL  " 4#7#7&&++-   d&6&6&D&DH^&^!!&&(~~++$$%,,Q/QT5F5FZ\]^ mm**, 	FKKM	rF   c                   | j                   j                  |      }|y|j                  j                  |j                  |j
                        ry|j                  j                  }|j                  }d }|rAt        |d      r5t        |j                  t              r|j                  j                  d      }t        ||      S )NTdetailstopologyVersion)rk   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancer9  dict _is_stale_error_topology_version)ry   r   err_ctxr   cur_tvr@  error_tvs          r;   _is_stale_errorzTopology._is_stale_error  s    ""7+><<(()@)@'BTBTU ##44WUI.%--. ==,,->?/AArF   c                n   | j                  ||      ry | j                  |   }|j                  }|j                  }| j                  j
                  r|s|j                  sy t        |t              r|j                  ry t        |t              ry t        |t        t        f      r#t        |d      r|j                  }n0t        |t              rdnd }|j                  j                  d|      }|t         j"                  v rw|t         j$                  v }| j                  j
                  s| j'                  t)        ||             |s|j*                  dk  r|j-                  |       |j/                          y |j                  sD| j                  j
                  s| j'                  t)        ||             |j-                  |       y y t        |t0              r^| j                  j
                  s| j'                  t)        ||             |j-                  |       |j2                  j5                          y y )Ncodei{'  r@     )rH  rk   r@  r>  rZ   rx   completed_handshakerB  r   r   r   r   rA  rJ  r9  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r#   max_wire_versionr   request_checkr   _monitorcancel_check)	ry   r   rE  r   r@  r>  err_codedefaultis_shutting_downs	            r;   _handle_errorzTopology._handle_error  s   1w'''
 >>''
7C^C^e^,1L1L
 z*1ABC uf% :: $.e_#E%4 ==,,VW=7555#+w/F/F#F ~~33(():7%)PQ#(@(@A(ELL,$$&00~~33(():7%)PQZ( 1 01 >>//$$%6we%LMLL$ OO((* 2rF   c                j    | j                   5  | j                  ||       ddd       y# 1 sw Y   yxY w)zHandle an application error.

        May reset the server to Unknown, clear the pool, and request an
        immediate check depending on the error and the context.
        N)rh   rW  )ry   r   rE  s      r;   r  zTopology.handle_error1  s0     ZZ 	1w0	1 	1 	1s   )2c                b    | j                   j                         D ]  }|j                           y)z3Wake all monitors. Hold the lock when calling this.N)rk   r   rQ  r7  s     r;   r   zTopology._request_check_all:  s*    mm**, 	#F  "	#rF   c           	        | j                   j                         j                         D ]S  \  }}|| j                  vr| j                  j                  || | j                  |      | j                        }d}| j                  r+| j                  t        j                  | j                        }t        || j                  |      || j                  | j                  |      }|| j                  |<   |j                          | j                  |   j                   j"                  }|| j                  |   _        ||j"                  k7  s"| j                  |   j$                  j'                  |j"                         V t)        | j                  j                               D ]L  \  }}| j                   j+                  |      r"|j-                          | j                  j/                  |       N y)zrSync our Servers from TopologyDescription.server_descriptions.

        Hold the lock while calling this.
        )r   topologyr   rz   N)r   r   monitortopology_id	listenersevents)r^   rd   r!  rk   rZ   monitor_class_create_pool_for_monitorrR   rU   rr   rs   r"   _create_pool_for_serverrM   rP   ru   r   is_writabler   update_is_writablerc   r   rt   pop)ry   r   r   r\  rD   r   was_writables          r;   r   zTopology._update_servers?  s   
  ,,@@BHHJ 	SKGRdmm+..66')!66w?&*nn	 7  ''DLL,D";;t||4D')55g># $ 1 1"oo *0g&  $}}W5AAMM57g&22>>1MM'*//BB2>>R=	S@  $DMM$7$7$9: 	+OGV$$//8!!'*	+rF   c                z    | j                   j                  || j                   j                  | j                        S )N)	client_id)rZ   
pool_classpool_optionsrM   r   s     r;   rb  z Topology._create_pool_for_serveri  s5    ~~((T^^00D<M<M ) 
 	
rF   c                H   | j                   j                  }t        |j                  |j                  |j                  |j
                  |j                  |j                  |j                  d|j                  	      }| j                   j                  ||d| j                        S )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshakerh  )rZ   rj  r!   rl  _ssl_contextro  rO   rq  rr  rt  ri  rM   )ry   r   optionsmonitor_pool_optionss       r;   ra  z!Topology._create_pool_for_monitorn  s    ..--
  +#33"22,,(/(K(K#44OO>>))
 
 ~~(()UdFWFW ) 
 	
rF   c                0   | j                   j                  t        j                  t        j                  fv }|rd}n,| j                   j                  t        j
                  k(  rd}nd}| j                   j                  r|t        u r|ryd|z  S d| d| dS t        | j                   j                               }t        | j                   j                         j                               }|s-|r&d	j                  || j                  j                        S d
|z  S |d   j                  t        fd|dd D              }|r=d|z  S |r)t!        |      j#                  | j$                        sd|z  S t'              S dj)                  d |D              S )zeFormat an error message if server selection fails.

        Hold the lock when calling this.
        zreplica set membersmongosesr   zNo primary available for writeszNo %s available for writeszNo z match selector ""z)No {} available for replica set name "{}"zNo %s availabler   c              3  <   K   | ]  }|j                   k(    y wrC   rK  ).0r   r@  s     r;   	<genexpr>z*Topology._error_message.<locals>.<genexpr>  s     Gv||u,Gs   r   NzNo %s found yetz\Could not reach any servers in %s. Replica set is configured with internal hostnames or IPs?,c              3  `   K   | ]&  }|j                   st        |j                          ( y wrC   )r@  str)r}  r   s     r;   r~  z*Topology._error_message.<locals>.<genexpr>  s     Xf6<<FLL 1Xs   ..)r^   r   r*   r   r   Shardedr  r(   rc   rd   r   formatrZ   r]   r@  allr   intersectionre   r  join)ry   r   is_replica_setserver_plural	addressesr   samer@  s          @r;   r   zTopology._error_message  s   
 **88//--=
 

 1M,,0E0EE&M%M**33!<7-GG]O+<XJaHHT..BBDEI4,,@@BIIKLG!FMM%77 
 -}<< AJ$$EG712;GGD=,}<<!#i.*E*EdFZFZ*[FHQR
 5z!xxXXXXrF   c                t    d}| j                   sd}d| j                  j                   d| | j                  dS )N zCLOSED < >)rf   	__class____name__r^   )ry   msgs     r;   __repr__zTopology.__repr__  s>    ||C4>>**+1SE$2C2C1FaHHrF   c                    | j                   }t        t        |j                              |j                  |j
                  |j                  fS )z?The properties to use for MongoClient/Topology equality checks.)rZ   tuplesortedra   r]   rw   srv_service_name)ry   tss     r;   eq_propszTopology.eq_props  s8    ^^fRXX&')<)<bggrGZGZ[[rF   c                |    t        || j                        r!| j                         |j                         k(  S t        S rC   )rB  r  r  NotImplemented)ry   others     r;   __eq__zTopology.__eq__  s.    eT^^,==?enn&666rF   c                4    t        | j                               S rC   )hashr  r  s    r;   __hash__zTopology.__hash__  s    DMMO$$rF   )rz   r/   )rK   None)rK   float)NNN)r    Callable[[Selection], Selection]r   r  r   Optional[float]r   Optional[_Address]r   Optional[int]rK   list[Server])r   r  r   r  r   r  r   r  r   r  rK   list[ServerDescription])NNNN)r   r  r   r  r   r  r   r  r   Optional[list[Server]]r   r  rK   r"   )NN)
r   r1   r   r  r   r  r   r  rK   r"   )FF)r   r#   r   rL   r   rL   rK   r  )r   zlist[tuple[str, Any]]rK   r  )r   r1   rK   zOptional[Server])r   r1   rK   rL   )rK   r  )r   r  rK   set[_Address])rK   r  )rK   zOptional[ClusterTime])r   Optional[Mapping[str, Any]]rK   r  )   )r  r   rK   r  )rK   r  )rK   r+   )rK   zlist[_ServerSession])r)  r  rK   r   )r.  r   r/  rL   rK   r  )rK   r$   )r   r1   rE  r  rK   rL   )r   r1   rE  r  rK   r  )r   r1   rK   r    )r   r  rK   r  )rK   r  )rK   z>tuple[tuple[_Address, ...], Optional[str], Optional[str], str])r  objectrK   rL   )rK   r   )0r  
__module____qualname____doc__r   ru   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r  r  r  r  rt   propertyr   r&  r(  r+  r   r   rH  rW  r  r   r   rb  ra  r   r  r  r  r   rF   r;   r>   r>   _   s   4NA`&"P 59&*&*#2# # #2	#
 $# $# 
#JJ#2J# J# 	J#
 $J# $J# 
!J#` 59&*8<&*2  #2	
 $  6 $ 
2 59&*8<&* 2    #2	 
 $   6  $  
 L 37&*

 
 #0	

 $
 

H !&+	@%-@% @%  $	@%
 
@%J !&+	\-\ \  $	\
 
\((3*(NPHF&6=,2"+: ! !0
R
MFBB(@+D1#
(+T


,8YtI\

%rF   r>   c                  ,    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddZy)r  z.An error with context for SDAM error handling.c                J    || _         || _        || _        || _        || _        y rC   )r@  rP  r=  rM  r>  )ry   r@  rP  r=  rM  r>  s         r;   r   z_ErrorContext.__init__  s*     
 0.#6 $rF   N)
r@  BaseExceptionrP  r   r=  r   rM  rL   r>  zOptional[ObjectId])r  r  r  r  r   r  rF   r;   r  r    s:    8%% % 	%
 "% '%rF   r  c                :    | |y| d   |d   k7  ry| d   |d   k\  S )z9Return True if the error's topologyVersion is <= current.F	processIdcounterr  )
current_tvrG  s     r;   rD  rD    s<     X-+(;"77i HY$777rF   c                j    | j                   |j                   }}||y|d   |d   k7  ry|d   |d   kD  S )z4Return True if the new topologyVersion is < current.Fr  r  )r?  )
current_sdnew_sdr  new_tvs       r;   r   r     sN    #44f6M6MJV^+&"55i 6)#444rF   c                H    |s| S | D cg c]	  }||vs| }}|xs | S c c}w )zBFilter out deprioritized servers from a list of server candidates.r  )
candidatesr   r   filtereds       r;   r   r     s;     !%/W66AV3VWHW !z! Xs   	)r6   z"weakref.ReferenceType[queue.Queue]rK   rL   )r  r  rG  r  rK   rL   )r  r#   r  r#   rK   rL   rC   )r  r  r   r  rK   r  )Tr  
__future__r   r   r   r4   r   r   r   r   rr   pathlibr   typingr   r   r   r   r	   r
   pymongor   r   r   r   pymongo.client_sessionr   r   pymongo.errorsr   r   r   r   r   r   r   r   pymongo.hellor   pymongo.lockr   pymongo.loggerr   r   r   r   pymongo.monitorr   pymongo.poolr    r!   pymongo.serverr"   pymongo.server_descriptionr#   pymongo.server_selectorsr$   r%   r&   r'   r(   pymongo.topology_descriptionr)   r*   r+   r,   r-   bsonr.   pymongo.settingsr/   pymongo.typingsr0   r1   r  __file__parentr   r<   r>   r  rD  r   r   r  rF   r;   <module>r     s   C "  	   
     H H = = E	 	 	   %  ' * ! 8   15 4>(()"p% p%f% %$8+87R8	85 OS
"
"5K
"
"rF   