o
    &!^±Ä  ã                
   @   sh  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zd dlZd dlm	Z	 e
eddƒZW n eyF   dZG dd„ dejƒZ	Y nw zd dlmZ W n ey`   G dd	„ d	eƒZY nw d d
lmZ d dlmZmZmZ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l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* d dl+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z9 d dl:m;Z;m<Z< d dl=m>Z>m?Z?m@Z@ d dlAmBZB d dlCmDZD d dlEmFZFmZ zd dlGmHZH dd„ ZIW n e�y   eJedƒ�rejK�rdd„ ZIndd„ ZIY nw zd dlLmLZLmMZMmNZNmOZO dd „ ZPW n e�y3   d!d „ ZPY nw d"ZQd#ZRd$ZSejd%k�r¥zd dlTZUW n e�yT   d dlUZUY nw z:eU VeUjWd&¡�(ZXeU YeXd'¡\ZZZ[eU YeXd(¡\Z\Z[e]eZeƒ�sve‚e]e\eƒ�s~e‚W d  ƒ n	1 �s‰w   Y  W n e^ef�yŸ   d)d*„ Z_Y nw d+d*„ Z_nd,d-„ Z`d.d*„ Z_ed/ed0d1efgƒfgƒZaej bd2¡�rõejcdd3… d4k �rØd5 dd6d7„ e e¡ D ƒ¡Zfne g¡ Zfed8e g¡ fd9effd:e h¡ fd1e i¡ fgƒead;< n¦ejd<k�red8e g¡ fd9e g¡ fd:e h¡ fd1e j¡ d  fgƒead;< nƒejd%k�rGed8e g¡ fd9d5 de g¡ e i¡ f¡fd:e h¡ fd1d= de k¡ d>d?… ¡fgƒead;< nTej bd@¡�rje l¡ dA \ZfZmZned8effd9effd:enfd1emfgƒead;< n1e oe g¡ e i¡ e p¡ ¡Zqed8e g¡ fd9d5 ddBd7„ eqdd3… D ƒ¡fd:e h¡ fd1eqd3 fgƒead;< e r¡  bdC¡�rÀd5 de r¡ dD deesejtƒ¡dEdD deesejcƒ¡ f¡eadF< n8ej bd@¡�ræd5 de r¡ dD deesejcƒ¡dGd5 de g¡ e i¡ f¡ f¡eadF< nd5 de r¡ dD deesejcƒ¡f¡eadF< dH udI¡ dYdJdK„ZvG dLdM„ dMewƒZxG dNdO„ dOewƒZydPdQ„ Zzejcdd3… dRkZ{dSdT„ Z|G dUdV„ dVe4ƒZ}G dWdX„ dXƒZ~dS )Zé    N)ÚSSLErrorÚHAS_SNIFc                   @   ó   e Zd ZdS )r   N©Ú__name__Ú
__module__Ú__qualname__© r	   r	   ú>/var/www/html/env/lib/python3.10/site-packages/pymongo/pool.pyr      ó    r   )ÚCertificateErrorc                   @   r   )Ú_SSLCertificateErrorNr   r	   r	   r	   r
   r   $   r   r   )ÚDEFAULT_CODEC_OPTIONS)ÚimapÚ
itervaluesÚ_unicodeÚinteger_types)ÚSON)ÚauthÚhelpersÚthread_utilÚ__version__)Ú_validate_session_write_concern)	ÚMAX_BSON_SIZEÚMAX_IDLE_TIME_SECÚMAX_MESSAGE_SIZEÚMAX_POOL_SIZEÚMAX_WIRE_VERSIONÚMAX_WRITE_BATCH_SIZEÚMIN_POOL_SIZEÚORDERED_TYPESÚWAIT_QUEUE_TIMEOUT)	ÚAutoReconnectÚConnectionFailureÚConfigurationErrorÚInvalidOperationÚDocumentTooLargeÚNetworkTimeoutÚNotMasterErrorÚOperationFailureÚPyMongoError)ÚIsMaster)Útime)ÚConnectionCheckOutFailedReasonÚConnectionClosedReason)ÚcommandÚreceive_messageÚSocketChecker)ÚReadPreference)ÚSERVER_TYPE)Úmatch_hostnamer   )Ú
ip_addressc              	   C   s,   z	t t| ƒƒ W dS  ttfy   Y dS w ©NTF)r5   r   Ú
ValueErrorÚUnicodeError©Úaddressr	   r	   r
   Úis_ip_addressO   s   ÿr;   Ú	inet_ptonc                 C   sR   zt  | ¡ W dS  t jy(   zt  t j| ¡ W Y dS  t jy'   Y Y dS w w r6   )ÚsocketÚ	inet_atonÚerrorr<   ÚAF_INET6r9   r	   r	   r
   r;   X   s   
ÿüc                 C   s6   zt  | ¡ W dS  t jy   d| v rY dS Y dS w )NTú:F)r=   r>   r?   r9   r	   r	   r
   r;   g   s   
	õ©ÚfcntlÚF_GETFDÚF_SETFDÚ
FD_CLOEXECc                 C   s   t | tƒ}t | t|tB ƒ dS )z8Set the close-on-exec flag on the given file descriptor.NrB   )ÚfdÚflagsr	   r	   r
   Ú_set_non_inheritable_non_atomicz   s   
rI   c                 C   s   dS )z6Dummy function for platforms that don't provide fcntl.Nr	   ©Údummyr	   r	   r
   rI   ‚   s   i,  é
   é	   Úwin32z2SYSTEM\CurrentControlSet\Services\Tcpip\ParametersÚKeepAliveTimeÚKeepAliveIntervalc                 C   s   d S ©Nr	   rJ   r	   r	   r
   Ú_set_keepalive_timesž   s   rR   c                 C   sH   t ttd ƒ}t ttd ƒ}|tk s|tk r"|  tjd||f¡ d S d S )Néè  é   )ÚminÚ_DEFAULT_TCP_IDLE_MSÚ_MAX_TCP_KEEPIDLEÚ_DEFAULT_TCP_INTERVAL_MSÚ_MAX_TCP_KEEPINTVLÚioctlr=   ÚSIO_KEEPALIVE_VALS)ÚsockÚidle_msÚinterval_msr	   r	   r
   rR   ¡   s   ÿÿÿc                 C   sb   t t|ƒr/tt|ƒ}z|  tj|¡}||kr!|  tj||¡ W d S W d S  tjy.   Y d S w d S rQ   )Úhasattrr=   ÚgetattrÚ
getsockoptÚIPPROTO_TCPÚ
setsockoptr?   )r\   Ú
tcp_optionÚ	max_valueÚsockoptÚdefaultr	   r	   r
   Ú_set_tcp_optionª   s   

ÿÿ÷rh   c                 C   s(   t | dtƒ t | dtƒ t | dtƒ d S )NÚTCP_KEEPIDLEÚTCP_KEEPINTVLÚTCP_KEEPCNT)rh   rW   rY   Ú_MAX_TCP_KEEPCNT©r\   r	   r	   r
   rR   ·   s   Údriver)ÚnameÚPyMongoÚversionÚlinuxé   )é   é   ú c                 C   ó   g | ]}|r|‘qS r	   r	   ©Ú.0Úpartr	   r	   r
   Ú
<listcomp>Ä   s    
ÿr{   Útypero   ÚarchitectureÚosÚdarwinú-rT   rt   Újavaéÿÿÿÿc                 C   rw   r	   r	   rx   r	   r	   r
   r{   ò   s    ÚPyPyÚ.z(Python %s)Úplatformz(%s)ÚfooÚidnac                 C   sr   | \}}|durd|||f }nd||f }|r|| }t |tjƒr&t|ƒ‚t |tƒr5dt|ƒv r5t|ƒ‚t|ƒ‚)z9Convert a socket.error to ConnectionFailure and raise it.Nz	%s:%d: %sz%s: %sz	timed out)Ú
isinstancer=   Útimeoutr'   r   Ústrr"   )r:   r?   Ú
msg_prefixÚhostÚportÚmsgr	   r	   r
   Ú_raise_connection_failure  s   r�   c                   @   sö   e Zd ZdZeeeddeddddddddfdd„Ze	dd„ ƒZ
e	dd	„ ƒZe	d
d„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	d d!„ ƒZe	d"d#„ ƒZe	d$d%„ ƒZdS )&ÚPoolOptions)Ú__max_pool_sizeÚ__min_pool_sizeÚ__max_idle_time_secondsÚ__connect_timeoutÚ__socket_timeoutÚ__wait_queue_timeoutÚ__wait_queue_multipleÚ__ssl_contextÚ__ssl_match_hostnameÚ__socket_keepaliveÚ__event_listenersÚ	__appnameÚ__driverÚ
__metadataÚ__compression_settingsNTc                 C   sì   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
|| _|| _|| _t t¡| _|r9d|i| jd< |rr|jrNdtd d |jf | jd d< |jradtd d |jf | jd d< |jrtdtd |jf | jd< d S d S d S )Nro   Úapplicationz%s|%srn   rq   r…   )Ú_PoolOptions__max_pool_sizeÚ_PoolOptions__min_pool_sizeÚ#_PoolOptions__max_idle_time_secondsÚ_PoolOptions__connect_timeoutÚ_PoolOptions__socket_timeoutÚ _PoolOptions__wait_queue_timeoutÚ!_PoolOptions__wait_queue_multipleÚ_PoolOptions__ssl_contextÚ _PoolOptions__ssl_match_hostnameÚ_PoolOptions__socket_keepaliveÚ_PoolOptions__event_listenersÚ_PoolOptions__appnameÚ_PoolOptions__driverÚ"_PoolOptions__compression_settingsÚcopyÚdeepcopyÚ	_METADATAÚ_PoolOptions__metadataro   rq   r…   )ÚselfÚmax_pool_sizeÚmin_pool_sizeÚmax_idle_time_secondsÚconnect_timeoutÚsocket_timeoutÚwait_queue_timeoutÚwait_queue_multipleÚssl_contextÚssl_match_hostnameÚsocket_keepaliveÚevent_listenersÚappnamern   Úcompression_settingsr	   r	   r
   Ú__init__/  s@   	
ÿÿ
ÿøzPoolOptions.__init__c                 C   s`   i }| j tkr| j |d< | jtkr| j|d< | jtkr"| jd |d< | jtkr.| jd |d< |S )zqThe non-default options this pool was created with.

        Added for CMAP's :class:`PoolCreatedEvent`.
        ÚmaxPoolSizeÚminPoolSizerS   ÚmaxIdleTimeMSÚwaitQueueTimeoutMS)r¡   r   r¢   r   r£   r   r¦   r!   )r³   Úoptsr	   r	   r
   Únon_default_options]  s   





zPoolOptions.non_default_optionsc                 C   ó   | j S )aQ  The maximum allowable number of concurrent connections to each
        connected server. Requests to a server will block if there are
        `maxPoolSize` outstanding connections to the requested server.
        Defaults to 100. Cannot be 0.

        When a server's pool has reached `max_pool_size`, operations for that
        server block waiting for a socket to be returned to the pool. If
        ``waitQueueTimeoutMS`` is set, a blocked operation will raise
        :exc:`~pymongo.errors.ConnectionFailure` after a timeout.
        By default ``waitQueueTimeoutMS`` is not set.
        )r¡   ©r³   r	   r	   r
   r´   n  s   zPoolOptions.max_pool_sizec                 C   rÈ   )zŠThe minimum required number of concurrent connections that the pool
        will maintain to each connected server. Default is 0.
        )r¢   rÉ   r	   r	   r
   rµ   }  ó   zPoolOptions.min_pool_sizec                 C   rÈ   )z¦The maximum number of seconds that a connection can remain
        idle in the pool before being removed and replaced. Defaults to
        `None` (no limit).
        )r£   rÉ   r	   r	   r
   r¶   „  s   z!PoolOptions.max_idle_time_secondsc                 C   rÈ   )zGHow long a connection can take to be opened before timing out.
        )r¤   rÉ   r	   r	   r
   r·   Œ  ó   zPoolOptions.connect_timeoutc                 C   rÈ   )zKHow long a send or receive on a socket can take before timing out.
        )r¥   rÉ   r	   r	   r
   r¸   ’  rË   zPoolOptions.socket_timeoutc                 C   rÈ   )zhHow long a thread will wait for a socket from the pool if the pool
        has no free sockets.
        )r¦   rÉ   r	   r	   r
   r¹   ˜  rÊ   zPoolOptions.wait_queue_timeoutc                 C   rÈ   )ztMultiplied by max_pool_size to give the number of threads allowed
        to wait for a socket at one time.
        )r§   rÉ   r	   r	   r
   rº   Ÿ  rÊ   zPoolOptions.wait_queue_multiplec                 C   rÈ   )z(An SSLContext instance or None.
        )r¨   rÉ   r	   r	   r
   r»   ¦  rË   zPoolOptions.ssl_contextc                 C   rÈ   )zCCall ssl.match_hostname if cert_reqs is not ssl.CERT_NONE.
        )r©   rÉ   r	   r	   r
   r¼   ¬  rË   zPoolOptions.ssl_match_hostnamec                 C   rÈ   )zZWhether to send periodic messages to determine if a connection
        is closed.
        )rª   rÉ   r	   r	   r
   r½   ²  rÊ   zPoolOptions.socket_keepalivec                 C   rÈ   )z;An instance of pymongo.monitoring._EventListeners.
        )r«   rÉ   r	   r	   r
   r¾   ¹  rË   zPoolOptions.event_listenersc                 C   rÈ   )zMThe application name, for sending with ismaster in server handshake.
        )r¬   rÉ   r	   r	   r
   r¿   ¿  rË   zPoolOptions.appnamec                 C   rÈ   )zIDriver name and version, for sending with ismaster in handshake.
        )r­   rÉ   r	   r	   r
   rn   Å  rË   zPoolOptions.driverc                 C   rÈ   rQ   )r®   rÉ   r	   r	   r
   rÀ   Ë  s   z PoolOptions.compression_settingsc                 C   s
   | j  ¡ S )zLA dict of metadata about the application, driver, os, and platform.
        )r²   r¯   rÉ   r	   r	   r
   ÚmetadataÏ  s   
zPoolOptions.metadata)r   r   r   Ú	__slots__r   r   r   r!   rÁ   ÚpropertyrÇ   r´   rµ   r¶   r·   r¸   r¹   rº   r»   r¼   r½   r¾   r¿   rn   rÀ   rÌ   r	   r	   r	   r
   r�   %  sV    
ù.














r�   c                   @   sÚ   e Zd ZdZdd„ Zdd„ Zdejeddddddddddddf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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d-d.„ ZdS )/Ú
SocketInfozÛStore a socket with some metadata.

    :Parameters:
      - `sock`: a raw socket object
      - `pool`: a Pool instance
      - `address`: the server's (host, port)
      - `id`: the id of this socket in it's pool
    c                 C   s’   || _ || _|| _tƒ | _d| _tƒ | _d| _d| _	t
| _t| _t| _t| _d| _d| _d| _|jj| _|j| _|jj| _d | _|j| _d| _d S )NF)r\   r:   ÚidÚsetÚauthsetÚclosedÚ_timeÚlast_checkin_timeÚperformed_handshakeÚis_writabler   Úmax_wire_versionr   Úmax_bson_sizer   Úmax_message_sizer   Úmax_write_batch_sizeÚsupports_sessionsÚ	is_mongosÚop_msg_enabledrÆ   r¾   Ú	listenersÚenabled_for_cmaprÀ   Úcompression_contextÚpool_idÚready)r³   r\   Úpoolr:   rÐ   r	   r	   r
   rÁ   ß  s*   


zSocketInfo.__init__c                 C   sÐ   t dgƒ}| js||d< | jr| jj|d< | jdkr"|d ur"||d< t| jd|dd�ƒ}|j| _|j| _|j| _|j	| _	|j
| _
|jd u| _|jtjk| _| js]| jr]| j |j¡}|| _d	| _|jdk| _|S )
N)ÚismasterrT   ÚclientÚcompressioné   z$clusterTimeÚadminF)Úpublish_eventsT)r   rÖ   rÀ   ÚcompressorsrØ   r+   r/   r×   rÙ   rÚ   rÛ   Úlogical_session_timeout_minutesrÜ   Úserver_typer3   ÚMongosrÝ   Úget_compression_contextrá   rÞ   )r³   rÌ   Úcluster_timeÚcmdrå   Úctxr	   r	   r
   rå   ù  s0   
ÿÿzSocketInfo.ismasterFTNc                 C   st  |   ||¡ t||
ƒ}t|tƒst|ƒ}|	r(| jdk r(|	js(td|	j| jf ƒ‚|
du s7|
j	s7|du s7tdƒ‚| jdkrG|
rG|
j
sG|
j|d< n| jdk rT|durTtdƒ‚|r]| |||¡ |  |||¡ |ri| jnd}|
op|
j	 }| jry|  |¡ z!t| j|||| j||||||| j||| j|	||| j| j||d�W S  ty¢   ‚  ty¹ } z|  |¡ W Y d}~dS d}~ww )	aF  Execute a command or raise an error.

        :Parameters:
          - `dbname`: name of the database on which to run the command
          - `spec`: a command document as a dict, SON, or mapping object
          - `slave_ok`: whether to set the SlaveOkay wire protocol bit
          - `read_preference`: a read preference
          - `codec_options`: a CodecOptions instance
          - `check`: raise OperationFailure if there are errors
          - `allowable_errors`: errors to ignore if `check` is True
          - `check_keys`: if True, check `spec` for invalid keys
          - `read_concern`: The read concern for this command.
          - `write_concern`: The write concern for this command.
          - `parse_write_concern_error`: Whether to parse the
            ``writeConcernError`` field in the command response.
          - `collation`: The collation for this command.
          - `session`: optional ClientSession instance.
          - `client`: optional MongoClient for gossipping $clusterTime.
          - `retryable_write`: True if this command is a retryable write.
          - `publish_events`: Should we publish events for this command?
          - `user_fields` (optional): Response fields that should be decoded
            using the TypeDecoders from codec_options, passed to
            bson._decode_all_selective.
        é   zDread concern level of %s is not valid with a max wire version of %d.Nz3Collation is unsupported for unacknowledged writes.ru   ÚwriteConcernz5Must be connected to MongoDB 3.4+ to use a collation.)Úparse_write_concern_errorÚ	collationÚcompression_ctxÚ
use_op_msgÚunacknowledgedÚuser_fields)Úvalidate_sessionr   rˆ   r    r   rØ   Úok_for_legacyr$   ÚlevelÚacknowledgedÚis_server_defaultÚdocumentÚ	_apply_toÚsend_cluster_timerß   rÞ   Ú_raise_if_not_writabler/   r\   rÝ   r:   rÙ   rá   r)   ÚBaseExceptionr�   )r³   ÚdbnameÚspecÚslave_okÚread_preferenceÚcodec_optionsÚcheckÚallowable_errorsÚ
check_keysÚread_concernÚwrite_concernrõ   rö   Úsessionræ   Úretryable_writerê   rú   rß   rù   r?   r	   r	   r
   r/     sj   %

ÿ
þÿÿ
ÿþÿ
ö€ÿzSocketInfo.commandc              
   C   sj   | j dur|| j krtd|| j f ƒ‚z	| j |¡ W dS  ty4 } z|  |¡ W Y d}~dS d}~ww )z}Send a raw BSON message or raise ConnectionFailure.

        If a network exception is raised, the socket is closed.
        NzfBSON document too large (%d bytes) - the connected server supports BSON document sizes up to %d bytes.)rÙ   r&   r\   Úsendallr  r�   )r³   ÚmessageÚmax_doc_sizer?   r	   r	   r
   Úsend_messagel  s   

þÿ€ÿzSocketInfo.send_messagec              
   C   sD   z	t | j|| jƒW S  ty! } z|  |¡ W Y d}~dS d}~ww )zzReceive a raw BSON message or raise ConnectionFailure.

        If any exception is raised, the socket is closed.
        N)r0   r\   rÚ   r  r�   )r³   Ú
request_idr?   r	   r	   r
   r0   }  s   ÿ€ÿzSocketInfo.receive_messagec                 C   s$   |r| j stdddddœƒ‚dS dS )z]Raise NotMasterError on unacknowledged write if this socket is not
        writable.
        z
not masterr   i{'  )ÚokÚerrmsgÚcodeN)r×   r(   )r³   rù   r	   r	   r
   r  ˆ  s
   
ÿþz!SocketInfo._raise_if_not_writablec                 C   s8   |   | ¡ |  ||¡ |r|  |¡}t | ¡ ¡S dS )aÓ  Send OP_INSERT, etc., optionally returning response as a dict.

        Can raise ConnectionFailure or OperationFailure.

        :Parameters:
          - `request_id`: an int.
          - `msg`: bytes, an OP_INSERT, OP_UPDATE, or OP_DELETE message,
            perhaps with a getlasterror command appended.
          - `max_doc_size`: size in bytes of the largest document in `msg`.
          - `with_last_error`: True if a getlasterror command is appended.
        N)r  r  r0   r   Ú_check_gle_responseÚcommand_response)r³   r  rŽ   r  Úwith_last_errorÚreplyr	   r	   r
   Úlegacy_write‘  s   
þzSocketInfo.legacy_writec                 C   s,   |   |d¡ |  |¡}| ¡ }t |¡ |S )zãSend "insert" etc. command, returning response as a dict.

        Can raise ConnectionFailure or OperationFailure.

        :Parameters:
          - `request_id`: an int.
          - `msg`: bytes, the command message.
        r   )r  r0   r  r   Ú_check_command_response)r³   r  rŽ   r  Úresultr	   r	   r
   Úwrite_command¤  s
   	

zSocketInfo.write_commandc                 C   sž   |s| j r7tt|ƒƒ}| j  ¡ }|| D ]}t |j| ¡ | j  |¡ q|| D ]}t || ¡ | j  	|¡ q(| j
sKd| _
| jrM| j | j| j¡ dS dS dS )a   Update this socket's authentication.

        Log in or out to bring this socket's credentials up to date with
        those provided. Can raise ConnectionFailure or OperationFailure.

        :Parameters:
          - `all_credentials`: dict, maps auth source to MongoCredential.
        TN)rÒ   rÑ   r   r¯   r   ÚlogoutÚsourceÚdiscardÚauthenticateÚaddrã   rà   rß   Úpublish_connection_readyr:   rÐ   )r³   Úall_credentialsÚcachedrÒ   Úcredentialsr	   r	   r
   Ú
check_authµ  s   
	
ýzSocketInfo.check_authc                 C   s   t  || ¡ | j |¡ dS )zÅLog in to the server and store these credentials in `authset`.

        Can raise ConnectionFailure or OperationFailure.

        :Parameters:
          - `credentials`: A MongoCredential.
        N)r   r$  rÒ   r%  )r³   r)  r	   r	   r
   r$  Ò  s   zSocketInfo.authenticatec                 C   s2   |r|j |urtdƒ‚|j| jkrtdƒ‚dS dS )z¼Validate this session before use with client.

        Raises error if this session is logged in as a different user or
        the client is not the one that created the session.
        z9Can only use session with the MongoClient that started itzBCannot use session after authenticating with different credentialsN)Ú_clientr%   Ú_authsetrÒ   )r³   ræ   r  r	   r	   r
   rû   Ý  s   
ÿÿúzSocketInfo.validate_sessionc                 C   s\   | j rdS d| _ z| j ¡  W n	 ty   Y nw |r*| jr,| j | j| j|¡ dS dS dS )z$Close this connection with a reason.NT)	rÓ   r\   ÚcloseÚ	Exceptionrà   rß   Úpublish_connection_closedr:   rÐ   )r³   Úreasonr	   r	   r
   Úclose_socketí  s   ÿ

ÿÿzSocketInfo.close_socketc                 C   s&   | j dkr|r| ||¡ dS dS dS )z$Add cluster time for MongoDB >= 3.6.rè   N)rØ   Ú_send_cluster_time)r³   r/   r  ræ   r	   r	   r
   r  ü  s   ÿzSocketInfo.send_cluster_timec                 C   s   t ƒ | _d S rQ   ©rÔ   rÕ   rÉ   r	   r	   r
   Úupdate_last_checkin_time  ó   z#SocketInfo.update_last_checkin_timec                 C   s
   || _ d S rQ   )r×   )r³   r×   r	   r	   r
   Úupdate_is_writable  ó   
zSocketInfo.update_is_writablec                 C   s   t ƒ | j S )z9Seconds since this socket was last checked into its pool.r3  rÉ   r	   r	   r
   Úidle_time_seconds  s   zSocketInfo.idle_time_secondsc                 C   s*   |   tj¡ t|tjƒrt| j|ƒ d S ‚ rQ   )r1  r.   ÚERRORrˆ   r=   r?   r�   r:   )r³   r?   r	   r	   r
   r�     s   z$SocketInfo._raise_connection_failurec                 C   s   | j |j kS rQ   rm   ©r³   Úotherr	   r	   r
   Ú__eq__  r5  zSocketInfo.__eq__c                 C   s
   | |k S rQ   r	   r:  r	   r	   r
   Ú__ne__"  r7  zSocketInfo.__ne__c                 C   s
   t | jƒS rQ   )Úhashr\   rÉ   r	   r	   r
   Ú__hash__%  r7  zSocketInfo.__hash__c                 C   s"   dt | jƒ| jr
dpdt| ƒf S )NzSocketInfo(%s)%s at %sz CLOSEDÚ )Úreprr\   rÓ   rÐ   rÉ   r	   r	   r
   Ú__repr__(  s
   ýzSocketInfo.__repr__)r   r   r   Ú__doc__rÁ   rå   r2   ÚPRIMARYr   r/   r  r0   r  r  r   r*  r$  rû   r1  r  r4  r6  r8  r�   r<  r=  r?  rB  r	   r	   r	   r
   rÏ   Ö  sH    
ôW	rÏ   c                 C   s–  | \}}|  d¡r4ttdƒstdƒ‚t tj¡}t| ¡ ƒ z| |¡ |W S  tjy3   | 	¡  ‚ w tj
}tjrA|dkrAtj}d}t |||tj¡D ]s}|\}}	}
}}zt ||	ttddƒB |
¡}W n tjyu   t ||	|
¡}Y nw t| ¡ ƒ z*| tjtjd¡ | |j¡ | tjtj|j¡ |jr�t|ƒ | |¡ |W   S  tjy¿ } z|}| 	¡  W Y d}~qLd}~ww |durÆ|‚t d	¡‚)
z³Given (host, port) and PoolOptions, connect and return a socket object.

    Can raise socket.error.

    This is a modified version of create_connection from CPython >= 2.7.
    z.sockÚAF_UNIXz-UNIX-sockets are not supported on this systemÚ	localhostNÚSOCK_CLOEXECr   rT   zgetaddrinfo failed)Úendswithr_   r=   r#   rE  rI   ÚfilenoÚconnectr?   r-  ÚAF_INETÚhas_ipv6Ú	AF_UNSPECÚgetaddrinfoÚSOCK_STREAMr`   rc   rb   ÚTCP_NODELAYÚ
settimeoutr·   Ú
SOL_SOCKETÚSO_KEEPALIVEr½   rR   )r:   ÚoptionsrŒ   r�   r\   ÚfamilyÚerrÚresÚafÚsocktypeÚprotorK   ÚsaÚer	   r	   r
   Ú_create_connection0  sZ   


þÿýÿ

€þ
r]  )rt   é   c              
   C   sô   t | |ƒ}|j}|durr| d }ztr!t|ƒrtr!|j||d�}n| |¡}W n' ty3   | ¡  ‚  tyN } z| ¡  t	| |dƒ W Y d}~nd}~ww |j
rrt|ddƒsr|jrrz
t| ¡ |d� W n tyq   | ¡  ‚ w | |j¡ |S )zµGiven (host, port) and PoolOptions, return a configured socket.

    Can raise socket.error, ConnectionFailure, or CertificateError.

    Sets socket's SSL and timeout options.
    Nr   )Úserver_hostnamezSSL handshake failed: Úcheck_hostnameF)Úhostname)r]  r»   Ú	_HAVE_SNIr;   Ú	_PY37PLUSÚwrap_socketr   r-  ÚIOErrorr�   Úverify_moder`   r¼   r4   Úgetpeercertr   rQ  r¸   )r:   rT  r\   r»   rŒ   Úexcr	   r	   r
   Ú_configured_socketx  s<   

€€û
ÿþþri  c                   @   s   e Zd ZdZdS )Ú_PoolClosedErrorzZInternal error raised when a thread tries to get a connection from a
    closed pool.
    N)r   r   r   rC  r	   r	   r	   r
   rj  ¨  s    rj  c                   @   s€   e Zd Zddd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	e
jddd„ƒZdd„ Zddd„Zdd„ Zdd„ Zdd„ ZdS ) ÚPoolTc                 C   sÞ   d| _ t ¡ | _t ¡ | _d| _d| _d| _	d| _
d| _t ¡ | _|| _|| _|| _| jo7| jjduo7| jjj| _| jjdu sE| jjdu rHd}n| jj| jj }t | jj|¡| _tƒ | _| jrm| jj | j| jj¡ dS dS )zÆ
        :Parameters:
          - `address`: a (hostname, port) tuple
          - `options`: a PoolOptions instance
          - `handshake`: whether to call ismaster for each new SocketInfo
        rT   r   FN)Ú_check_interval_secondsÚcollectionsÚdequeÚsocketsÚ	threadingÚLockÚlockÚactive_socketsÚnext_connection_idrÓ   r×   râ   r~   ÚgetpidÚpidr:   rÆ   Ú	handshaker¾   rà   rº   r´   r   Úcreate_semaphoreÚ_socket_semaphorer1   Úsocket_checkerÚpublish_pool_createdrÇ   )r³   r:   rT  rw  Úmax_waitersr	   r	   r
   rÁ   ²  s>   	



ÿýÿÿ
ÿÿzPool.__init__c                 C   sà   | j �1 | jr	 W d   ƒ d S |  jd7  _t ¡ | _| jt ¡ }| _d| _	|r-d| _W d   ƒ n1 s7w   Y  | j
j}|rZ|D ]}| tj¡ qD| jrX| | j¡ d S d S | jrc| | j¡ |D ]}| tj¡ qed S )NrT   r   T)rr  rÓ   râ   r~   ru  rv  ro  rm  rn  rs  rÆ   r¾   r1  r.   ÚPOOL_CLOSEDrà   Úpublish_pool_closedr:   Úpublish_pool_clearedÚSTALE)r³   r-  ro  rß   Ú	sock_infor	   r	   r
   Ú_resetã  s0   þ
€ø
ÿÿzPool._resetc                 C   sJ   || _ | j� | jD ]}| | j ¡ q
W d  ƒ dS 1 sw   Y  dS )zXUpdates the is_writable attribute on all sockets currently in the
        Pool.
        N)r×   rr  ro  r6  )r³   r×   r=   r	   r	   r
   r6  ý  s   
ÿ"ÿzPool.update_is_writablec                 C   ó   | j dd� d S )NF©r-  ©r‚  rÉ   r	   r	   r
   Úreset  ó   z
Pool.resetc                 C   rƒ  )NTr„  r…  rÉ   r	   r	   r
   r-  	  r‡  z
Pool.closec                 C   sn  | j jdur@| j�/ | jr1| jd  ¡ | j jkr1| j ¡ }| tj¡ | jr1| jd  ¡ | j jksW d  ƒ n1 s;w   Y  	 | j� t	| jƒ| j
 | j jkrZ	 W d  ƒ dS W d  ƒ n1 sdw   Y  | j d¡sqdS z>|  ¡ }| j�( | j|kr”| tj¡ 	 W d  ƒ W | j ¡  dS | j |¡ W d  ƒ n1 s¤w   Y  W | j ¡  n| j ¡  w qA)zîRemoves stale sockets then adds new ones if pool is too small and
        has not been reset. The `reference_pool_id` argument specifies the
        `pool_id` at the point in time this operation was requested on the
        pool.
        Nr‚   TF)rÆ   r¶   rr  ro  r8  Úpopr1  r.   ÚIDLEÚlenrs  rµ   ry  ÚacquirerJ  râ   r€  ÚreleaseÚ
appendleft)r³   Úreference_pool_idr�  r	   r	   r
   Úremove_stale_sockets  sD   
ý€þÿüÿ
ûþú€ìzPool.remove_stale_socketsc              
   C   sú   | j � | j}|  jd7  _W d  ƒ n1 sw   Y  | jj}| jr+| | j|¡ d}z	t| j| jƒ}W n- tj	yc } z |durG| 
¡  | jrS| | j|tj¡ t| j|ƒ W Y d}~nd}~ww t|| | j|ƒ}| jr{| | jjd¡ |j| _|S )z÷Connect to Mongo and return a new SocketInfo.

        Can raise ConnectionFailure or CertificateError.

        Note that the pool does not keep a reference to the socket -- you
        must call return_socket() when you're done with it.
        rT   N)rr  rt  rÆ   r¾   rà   Úpublish_connection_createdr:   ri  r=   r?   r-  r/  r.   r9  r�   rÏ   rw  rå   rÌ   r×   )r³   Úconn_idrß   r\   r?   r�  r	   r	   r
   rJ  /  s2   þ
ÿ€ø
zPool.connectFc                 c   s¢   � | j j}| jr| | j¡ |  ¡ }d}z| |¡ d}| jr'| | j|j¡ |V  W n   | j	||d� | jrE|sE| j j 
| jtj¡ ‚ |sO|  	|¡ dS dS )a,  Get a socket from the pool. Use with a "with" statement.

        Returns a :class:`SocketInfo` object wrapping a connected
        :class:`socket.socket`.

        This method should always be used in a with-statement::

            with pool.get_socket(credentials, checkout) as socket_info:
                socket_info.send_message(msg)
                data = socket_info.receive_message(op_code, request_id)

        The socket is logged in or out as needed to match ``all_credentials``
        using the correct authentication mechanism for the server's wire
        protocol version.

        Can raise ConnectionFailure or OperationFailure.

        :Parameters:
          - `all_credentials`: dict, maps auth source to MongoCredential.
          - `checkout` (optional): keep socket checked out.
        FT)Úpublish_checkinN)rÆ   r¾   rà   Ú$publish_connection_check_out_startedr:   Ú_get_socket_no_authr*  Úpublish_connection_checked_outrÐ   Úreturn_socketÚ#publish_connection_check_out_failedr-   Ú
CONN_ERROR)r³   r'  Úcheckoutrß   r�  Úchecked_authr	   r	   r
   Ú
get_socketS  s0   €
ÿ

ÿÿzPool.get_socketc                 C   st  | j t ¡ kr|  ¡  | jr| jr| jj | j	t
j¡ tdƒ‚| j d| jj¡s,|  ¡  | j� |  jd7  _W d  ƒ n1 sAw   Y  z?d}|du rƒz| j� | j ¡ }W d  ƒ n1 saw   Y  W n tyt   |  ¡ }Y nw |  |¡r|d}|du sMW |S W |S  ty¹   | j ¡  | j� |  jd8  _W d  ƒ n1 s¦w   Y  | jr¸| jj | j	t
j¡ ‚ w )z8Get or create a SocketInfo. Can raise ConnectionFailure.z?Attempted to check out a connection from closed connection poolTrT   N)rv  r~   ru  r†  rÓ   rà   rÆ   r¾   r—  r:   r-   r}  rj  ry  r‹  r¹   Ú_raise_wait_queue_timeoutrr  rs  ro  ÚpopleftÚ
IndexErrorrJ  Ú	_perishedr.  rŒ  r˜  ©r³   r�  r	   r	   r
   r”  ƒ  sZ   ÿÿÿÿÿ€þ

÷ìö
ÿÿøzPool._get_socket_no_authc                 C   sø   | j j}| jr|r| | j|j¡ | jt ¡ kr|  	¡  n=| j
r'| tj¡ n3|j| jkr4| tj¡ n&|j
sZ| ¡  | | j¡ | j� | j |¡ W d  ƒ n1 sUw   Y  | j ¡  | j� |  jd8  _W d  ƒ dS 1 suw   Y  dS )zþReturn the socket to the pool, or if it's closed discard it.

        :Parameters:
          - `sock_info`: The socket to check into the pool.
          - `publish_checkin`: If False, a ConnectionCheckedInEvent will not
            be published.
        NrT   )rÆ   r¾   rà   Úpublish_connection_checked_inr:   rÐ   rv  r~   ru  r†  rÓ   r1  r.   r}  râ   r€  r4  r6  r×   rr  ro  r�  ry  rŒ  rs  )r³   r�  r’  rß   r	   r	   r
   r–  ³  s&   

ÿ
"ÿzPool.return_socketc                 C   sp   |  ¡ }| jjdur|| jjkr| tj¡ dS | jdur6d| jks'|| jkr6| j |j	¡r6| tj
¡ dS dS )a;  This side-effecty function checks if this socket has been idle for
        for longer than the max idle time, or if the socket has been closed by
        some external network error.

        Checking sockets lets us avoid seeing *some*
        :class:`~pymongo.errors.AutoReconnect` exceptions on server
        hiccups, etc. We only check if the socket was closed by an external
        error if it has been > 1 second since the socket was checked into the
        pool, to keep performance reasonable - we can't avoid AutoReconnects
        completely anyway.
        NTr   F)r8  rÆ   r¶   r1  r.   r‰  rl  rz  Úsocket_closedr\   r9  )r³   r�  r8  r	   r	   r
   rŸ  Ï  s   


zPool._perishedc                 C   s6   | j j}| jr| | jtj¡ td| j j| j j	f ƒ‚)NziTimed out while checking out a connection from connection pool with max_size %r and wait_queue_timeout %r)
rÆ   r¾   rà   r—  r:   r-   ÚTIMEOUTr#   r´   r¹   )r³   rß   r	   r	   r
   rœ  ë  s   ÿÿÿÿzPool._raise_wait_queue_timeoutc                 C   s   | j D ]}| d ¡ qd S rQ   )ro  r1  r   r	   r	   r
   Ú__del__õ  s   
ÿzPool.__del__N)T)F)r   r   r   rÁ   r‚  r6  r†  r-  r�  rJ  Ú
contextlibÚcontextmanagerr›  r”  r–  rŸ  rœ  r¤  r	   r	   r	   r
   rk  ±  s    
1	#$/
0
rk  rQ   )r¥  r¯   r~   r…   r=   Úsysrp  rm  Ússlr   r`   rb  ÚImportErrorr?   r   r   r7   Úbsonr   Úbson.py3compatr   r   r   r   Úbson.sonr   Úpymongor   r   r   r   Úpymongo.client_sessionr   Úpymongo.commonr   r   r   r   r   r   r   r    r!   Úpymongo.errorsr"   r#   r$   r%   r&   r'   r(   r)   r*   Úpymongo.ismasterr+   Úpymongo.monotonicr,   rÔ   Úpymongo.monitoringr-   r.   Úpymongo.networkr/   r0   r1   Úpymongo.read_preferencesr2   Úpymongo.server_typer3   Úpymongo.ssl_match_hostnamer4   Ú	ipaddressr5   r;   r_   rL  rC   rD   rE   rF   rI   rW   rY   rl   Ú_winregÚwinregÚOpenKeyÚHKEY_LOCAL_MACHINEÚkeyÚQueryValueExrV   Ú_rX   rˆ   ÚOSErrorrR   rh   r±   Ú
startswithÚversion_infoÚjoinÚlinux_distributionÚ_nameÚsystemÚmachinerŒ  Úmac_verÚ	win32_verÚjava_verÚ_verÚ_archÚsystem_aliasrq   Ú_aliasedÚpython_implementationrŠ   Úpypy_version_infoÚencoder�   Úobjectr�   rÏ   r]  rc  ri  rj  rk  r	   r	   r	   r
   Ú<module>   s>  þÿ,,		
€î#üÿþÿÿ÷€þ
	ÿ

ÿ


û


ú

úùÿ



üþ
ÿþ
ÿÿÿ
	
 2  \E0	