
    =h                       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      ZE	 	 	 	 	 	 ddZFddZGy)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_Addressc                     |        }|sy	 	 |j                         }|\  }} ||  # t        j                  $ r Y yw xY w)NFT)
get_nowaitqueueEmpty)	queue_refqeventfnargss        `/var/www/html/phonemate/phone_mate_backend/venv/lib/python3.12/site-packages/pymongo/topology.pyprocess_events_queuer9   D   sV    A
	LLNE HBI  {{ 	
 	s   ( >>c                     e Zd ZdZd0dZd1dZd2dZ	 	 d3	 	 	 	 	 	 	 d4dZ	 	 	 	 	 	 	 	 d5dZ	 	 d3	 	 	 	 	 	 	 d6dZ		 	 d3	 	 	 	 	 	 	 d6d	Z
	 d7	 	 	 	 	 d8d
Z	 d9	 	 	 	 	 d:dZd9d: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dBdZdBdZdCdDdZdEdZd1dZd1dZedFd       ZdGdZd1dZ d2dZ!dHd Z"dId!Z#dJd"Z$d1d#Z%dKd$Z&dLd%Z'dLd&Z(d1d'Z)d1d(Z*dMd)Z+dMd*Z,dNd+Z-dOd,Z.dPd-Z/dQd.Z0dRd/Z1y)S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)r9   )weaks   r8   targetz!Topology.__init__.<locals>.target   s    +D11    pymongo_events_thread)intervalmin_intervalrB   name)returnbool)4_topology_id_pool_options_event_listeners
_listenersenabled_for_server_publish_serverenabled_for_topology_publish_tp_events_Topology__events_executorr1   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seedrB   executorrA   s          @r8   __init__zTopology.__init__X   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 &++D##||///  $//"G"G$PTPaPaIb!cd ,  $$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*rC   c                   t        j                         }| j                  || _        n|| j                  k7  r||| _        t        j                  dd       | 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.

        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getpidri   warningswarnre   rh   valuesrq   rk   reset_ensure_opened)rv   pidservers      r8   rr   zTopology.open   s     iik99DIDIIDIMM'  "mm224FLLN 5 ""((*  ZZ! Z  Zs   "A
C C&C#&C/c                ^    t        j                         }|| j                  j                  S |S r@   )r
   	remainingrW   server_selection_timeout)rv   timeouts     r8   get_server_selection_timeoutz%Topology.get_server_selection_timeout   s(    //#?>>:::rC   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)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.
        N)r   re   _select_servers_loopr	   r   get_server_by_addressaddress)rv   selectorr   r   server_timeoutra   sds          r8   select_serverszTopology.select_servers   s    * $+!>>@N5NZZ"&";";HnV]"^ PcObVT77

CDOb Z Zs   A;0A6*A;6A;;Bc                   t        j                         }||z   }| j                  j                  ||| j                  j
                        }|s|dk(  s||kD  r,t        | j                  |       d| d| j                        | j                          | j                          | j                  j                  t        j                         | j                  j                          t        j                         }| j                  j                  ||| j                  j
                        }|s| j                  j                          |S )z7select_servers() guts. Hold the lock when calling this.)custom_selectorr   z, Timeout: zs, Topology Description: )time	monotonicr[   apply_selectorrW   server_selectorr   _error_messagedescriptionr   _request_check_allrg   waitr   rn   check_compatible)rv   r   r   r   nowend_timera   s          r8   r   zTopology._select_servers_loop   s-    nn="//>>gt~~/M/M ? 
 &!|sX~1**845[	Ibcgcscsbvw  !##% OO  !>!>?..0.."C"&"3"3"B"B'4>>3Q3Q #C ## &* 	**,""rC   c                    | j                  |||      }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)rv   r   r   r   serversserver1server2s          r8   _select_serverzTopology._select_server  sj     %%h0H'Rw<11:!==!4<<''7<<+G+GGNNrC   c                    | j                  |||      }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)rv   r   r   r   r   s        r8   select_serverzTopology.select_server'  sB     $$X/GQMM&,,@@ArC   c                0    | 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.

        :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!   )rv   r   r   s      r8   select_server_by_addressz!Topology.select_server_by_address3  s    ( !!"57OQXYYrC   c                0   | 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                          |rA| j                  j                  |j                        }|r|j                  j;                          | j<                  j?                          y)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'   Singlerh   getr   readyrO   rQ   rR   rU   rM   "publish_server_description_changedrJ   _update_servers_receive_cluster_time_no_lockcluster_timer]   rs   r\   r&   rq   r   rg   
notify_all)rv   server_description
reset_pooltd_oldsd_oldnew_tdr   suppress_events           r8   _process_changezTopology._process_changeI  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!!# 	""$rC   c                    | j                   5  | j                  r7| 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)re   rc   r[   
has_serverr   r   )rv   r   r   s      r8   	on_changezTopology.on_change  sI     ZZ || 1 1 < <=O=W=W X$$%7D ZZs   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   rQ   rR   rU   rM   r]   rJ   )rv   seedlistr   s      r8   _process_srv_updatezTopology._process_srv_update  s     ""'==EdFWFWYab<<+++LLOOHHT..0A0AB rC   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)re   rc   r   )rv   r   s     r8   on_srv_updatezTopology.on_srv_update  s*     ZZ||((2 ZZs   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.
        )rh   r   rv   r   s     r8   r   zTopology.get_server_by_address  s     }}  ))rC   c                    || j                   v S r@   )rh   r   s     r8   r   zTopology.has_server  s    $--''rC   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   )re   r[   r   r'   ReplicaSetWithPrimaryr%   _new_selectionr   )rv   r   s     r8   get_primaryzTopology.get_primary  s\     ZZ --;;M C CC Z
 ,D,?,?,AB1EMM ZZs   +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)
re   r[   r   r'   r   ReplicaSetNoPrimarysetiterr   r   )rv   r   r   r   s       r8   _get_replica_set_membersz!Topology._get_replica_set_members  s     ZZ --;;M3311%  u Z *.ht7J7J7L.M)NO)N2BJJ)NO Z P Zs$   AB!B:BBBB'c                ,    | j                  t              S )z"Return set of secondary addresses.)r   r$   rv   s    r8   get_secondarieszTopology.get_secondaries  s    ,,-FGGrC   c                ,    | j                  t              S )z Return set of arbiter addresses.)r   r"   r   s    r8   get_arbiterszTopology.get_arbiters  s    ,,-DEErC   c                    | j                   S )z1Return a document, the highest seen $clusterTime.rj   r   s    r8   max_cluster_timezTopology.max_cluster_time  s    %%%rC   c                \    |r*| j                   r|d   | j                   d   kD  r|| _         y y y )NclusterTimer   rv   r   s     r8   r   z&Topology._receive_cluster_time_no_lock  s=      **.1G1G1VV)5& W	 rC   c                h    | j                   5  | j                  |       d d d        y # 1 sw Y   y xY wr@   )re   r   r   s     r8   receive_cluster_timezTopology.receive_cluster_time  s!    ZZ..|< ZZs   (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)re   r   rg   r   )rv   	wait_times     r8   request_check_allzTopology.request_check_all  s1    ZZ##%OO  + ZZs   ,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    r8   data_bearing_serverszTopology.data_bearing_servers  sB    
 **m.B.BB$$222  111rC   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)re   r   rh   r   appendr   genget_overallremove_stale_socketsr   _ErrorContexthandle_errorr   )rv   r   r   r   
generationexcctxs          r8   update_poolzTopology.update_pool  s    ZZ//1rzz2(C(C(EFG 2  #*FJ00< #* Z   #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)re   rh   r   rq   r[   r   ra   itemsr   rs   rc   rd   rQ   rR   rU   rM   publish_topology_closedrJ   rO   rS   )rv   r   r   r   s       r8   rq   zTopology.close  s-   
 ZZ--..0 1 !% 1 1 7 7 9D#00DDFLLNdmm+9;DMM'*6  O
   !!'') DLDL $ <<+++LLdooEEHYHYG[\]4#3#3""((* $4+ Zs   BE5A
E55E>c                    | j                   S r@   )r[   r   s    r8   r   zTopology.description2  s       rC   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)re   rk   pop_allr   s    r8   pop_all_sessionszTopology.pop_all_sessions6  s%    ZZ%%--/ ZZs   1:c                f    | j                   5  | j                          d d d        y # 1 sw Y   y xY wr@   )re   _check_session_supportr   s    r8   _check_implicit_session_supportz(Topology._check_implicit_session_support;  s    ZZ'') ZZs   '0c                   | j                   j                  rt        d      S | j                  j                  }|| j                  j
                  t        j                  k(  r<| j                  j                  sa| j                  t        | j                         d       n;| j                  j                  s%| j                  t        | j                         d       | j                  j                  }|t        d      |S )z/Internal check for session support on clusters.infNz5Sessions are not supported by this MongoDB deployment)rW   ru   floatr[   logical_session_timeout_minutesr   r'   r   has_known_serversr   r!   r   r   r#   r   rv   session_timeouts     r8   r  zTopology._check_session_support?  s    >>''<++KK"  ..-2F2FF((::--+T-N-N-PRV &&77)),d.O.O.QSW #//OOO&()`aarC   c                    | j                   5  | j                         }| 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)re   r  rk   get_server_sessionr  s     r8   r  zTopology.get_server_sessionV  s5    ZZ"99;O%%88I ZZs   +AAc                    |rF| j                   5  | j                  j                  || j                  j                         d d d        y | j                  j                  |       y # 1 sw Y   y xY wr@   )re   rk   return_server_sessionr[   r
  return_server_session_no_lock)rv   server_sessionlocks      r8   r  zTopology.return_server_session\  sV    ""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    r8   r   zTopology._new_selectionf  s    
 2243D3DEErC   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)rd   r   rc   r   rQ   rO   rS   rr   rs   r   r   r&   rW   ru   r   r   rb   r   rJ   rh   r   rv   r   s     r8   r   zTopology._ensure_openedm  s    
 <<"#GHH||DL  " 4#7#7&&++-   d&6&6&D&DH^&^!!&&(~~++$$%,,Q/QT5F5FZ\]^ mm**,FKKM -rC   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)rh   r   _poolstale_generationsock_generation
service_idr   topology_versionerrorhasattr
isinstancer  dict _is_stale_error_topology_version)rv   r   err_ctxr   cur_tvr%  error_tvs          r8   _is_stale_errorzTopology._is_stale_error  s    ""7+><<(()@)@'BTBTU ##44WUI.%--. ==,,->?/AArC   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%     )r-  rh   r%  r#  rW   ru   completed_handshaker'  r   r   r   r   r&  r/  r  r   r   _NOT_PRIMARY_CODES_SHUTDOWN_CODESr   r   max_wire_versionr   request_checkr   _monitorcancel_check)	rv   r   r*  r   r%  r#  err_codedefaultis_shutting_downs	            r8   _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((* 2rC   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)re   r<  )rv   r   r*  s      r8   r   zTopology.handle_error  s%     ZZw0 ZZs   )2c                b    | j                   j                         D ]  }|j                           y)z3Wake all monitors. Hold the lock when calling this.N)rh   r   r6  r  s     r8   r   zTopology._request_check_all  s%    mm**,F  " -rC   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   rw   N)r   r   monitortopology_id	listenersevents)r[   ra   r   rh   rW   monitor_class_create_pool_for_monitorrO   rR   ro   rp   r   _create_pool_for_serverrJ   rM   rr   r   is_writabler   update_is_writabler`   r   rq   pop)rv   r   r   rA  rA   r   was_writables          r8   r   zTopology._update_servers  s   
  ,,@@BHHJKGR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= K@  $DMM$7$7$9:OGV$$//8!!'*  ;rC   c                b    | j                   j                  || j                   j                        S r@   )rW   
pool_classpool_optionsr   s     r8   rG  z Topology._create_pool_for_server  s#    ~~(($..2M2MNNrC   c                2   | j                   j                  }t        |j                  |j                  |j                  |j
                  |j                  |j                  |j                  d|j                  	      }| j                   j                  ||d      S )NF)	connect_timeoutsocket_timeoutssl_contexttls_allow_invalid_hostnamesevent_listenersappnamedriverpause_enabled
server_api)	handshake)rW   rN  r   rP  _ssl_contextrS  rL   rU  rV  rX  rM  )rv   r   optionsmonitor_pool_optionss       r8   rF  z!Topology._create_pool_for_monitor  s    ..--
  +#33"22,,(/(K(K#44OO>>))
 
 ~~((2FRW(XXrC   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r@   r0  ).0r   r%  s     r8   	<genexpr>z*Topology._error_message.<locals>.<genexpr>\  s     G;v||u,;s   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r@   )r%  str)ra  r   s     r8   rb  z*Topology._error_message.<locals>.<genexpr>k  s      Xf6<<FLL 1s   ..)r[   r   r'   r   r   Shardedr   r%   r`   ra   r   formatrW   rZ   r%  allr   intersectionrb   re  join)rv   r   is_replica_setserver_plural	addressesr   samer%  s          @r8   r   zTopology._error_message3  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XrC   c                t    d}| j                   sd}d| j                  j                   d| | j                  dS )N zCLOSED < >)rc   	__class____name__r[   )rv   msgs     r8   __repr__zTopology.__repr__m  s>    ||C4>>**+1SE$2C2C1FaHHrC   c                    | j                   }t        t        |j                              |j                  |j
                  |j                  fS )z?The properties to use for MongoClient/Topology equality checks.)rW   tuplesortedr^   rZ   rt   srv_service_name)rv   tss     r8   eq_propszTopology.eq_propss  s8    ^^fRXX&')<)<bggrGZGZ[[rC   c                |    t        || j                        r!| j                         |j                         k(  S t        S r@   )r'  rt  r}  NotImplemented)rv   others     r8   __eq__zTopology.__eq__x  s.    eT^^,==?enn&666rC   c                4    t        | j                               S r@   )hashr}  r   s    r8   __hash__zTopology.__hash__}  s    DMMO$$rC   )rw   r,   )rH   None)rH   r	  )NN)r    Callable[[Selection], Selection]r   Optional[float]r   Optional[_Address]rH   zlist[Server])r   r  r   r	  r   r  rH   list[ServerDescription])r   r  r   r  r   r  rH   r   r@   )r   r.   r   zOptional[int]rH   r   )F)r   r   r   rI   rH   r  )r   zlist[tuple[str, Any]]rH   r  )r   r.   rH   zOptional[Server])r   r.   rH   rI   )rH   r  )r   r  rH   set[_Address])rH   r  )rH   zOptional[ClusterTime])r   Optional[Mapping[str, Any]]rH   r  )   )r   intrH   r  )rH   r  )rH   r(   )rH   zlist[_ServerSession])rH   r   )r  r   r  rI   rH   r  )rH   r    )r   r.   r*  r   rH   rI   )r   r.   r*  r   rH   r  )r   r.   rH   r   )r   r  rH   re  )rH   re  )rH   z>tuple[tuple[_Address, ...], Optional[str], Optional[str], str])r  objectrH   rI   )rH   r  )2ru  
__module____qualname____doc__r|   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   propertyr   r  r  r  r  r  r   r   r-  r<  r   r   r   rG  rF  r   rw  r}  r  r   rC   r8   r;   r;   U   s   4NA`!"F 59&*	2 #2 $	
 
B##2## ## $	##
 
!##P 59&*	2 #2 $	
 
$ 59&*	
2
 #2
 $	

 

 LPZZ;HZ	Z. IN=%"3=%AE=%	=%~E(3*(NPHF&6=,2"+: ! !0
*.JMFBB(@+D1#
(+TOY(8YtI\

%rC   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 r@   )r%  r5  r"  r2  r#  )rv   r%  r5  r"  r2  r#  s         r8   r|   z_ErrorContext.__init__  s*     
 0.#6 $rC   N)
r%  BaseExceptionr5  r  r"  r  r2  rI   r#  zOptional[ObjectId])ru  r  r  r  r|   r  rC   r8   r   r     s:    8%% % 	%
 "% '%rC   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_tvr,  s     r8   r)  r)    s<     X-+(;"77i HY$777rC   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       r8   r   r     sN    #44f6M6MJV^+&"55i 6)#444rC   )r3   z"weakref.ReferenceType[queue.Queue]rH   rI   )r  r  r,  r  rH   rI   )r  r   r  r   rH   rI   )Hr  
__future__r   r   r1   r   r   r   ro   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.   r9   r;   r   r)  r   r  rC   r8   <module>r     s    C " 	      H H = = E
 
 
   % & * ! 8   15"i% i%X% %$8+87R8	85rC   