o Sb0 @sUddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z m Z mZddlmZddlmZddlmZmZmZmZddlmZddlmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1dd l2m3Z3m4Z4dd l5m6Z6m7Z7dd l8m9Z9m:Z:dd l;mZ>ddl?m@Z@ddlAmBZBddlCmDZDmEZEzddlFmGZGmHZHmIZImFZFddZJWn eKyddZJYnwdZLdZMdZNejdkr@zddlOZPWneKyddlPZPYnwddZQz&ePRePjSdZTeQeTddZUeQeTddZVWdn 1s&wYWneWy:dZUdZVYnwd d!ZXnd"d#ZYd$d!ZXed%ed&d'efgfgZZee[e fe\d(<ej]d)re^Z_ed*e_fd+e_fd,e`fd'eafgeZd-<nejd.kred*e^fd+e^fd,e`fd'ebdfgeZd-<nejdkred*e^fd+d/ce^eaffd,e`fd'd0cedd1d2fgeZd-<nTej]d3reed4\Z_ZfZged*e_fd+e_fd,egfd'effgeZd-<n1ehe^eaeiZjed*e^fd+d/cd5d6ejdd7Dfd,e`fd'ejd7fgeZd-<ek]d8rJd/cekd9cele[ejmd:d9cele[ejnfeZd;<n8ej]d3rpd/cekd9cele[ejnd dYd?e d@epdAee[dBe fdCdDZqdEdFZrGdGdHdHesZtGdIdJdJesZuGdKdLdLesZvdMdNZwdOdPZxGdQdRdRe/ZyGdSdTdTesZzGdUdVdVesZ{GdWdXdXZ|dS)ZN)AnyNoReturnOptional)DEFAULT_CODEC_OPTIONS)SON) __version___csotauthhelpers)_validate_session_write_concern) MAX_BSON_SIZEMAX_CONNECTINGMAX_IDLE_TIME_SECMAX_MESSAGE_SIZE MAX_POOL_SIZEMAX_WIRE_VERSIONMAX_WRITE_BATCH_SIZE MIN_POOL_SIZE ORDERED_TYPESWAIT_QUEUE_TIMEOUT) AutoReconnectConfigurationErrorConnectionFailureDocumentTooLargeExecutionTimeoutInvalidOperationNetworkTimeoutNotPrimaryErrorOperationFailure PyMongoErrorWaitQueueTimeoutError_CertificateError)Hello HelloCompat)ConnectionCheckOutFailedReasonConnectionClosedReason)commandreceive_message)ReadPreference)_add_to_command) SERVER_TYPE) SocketChecker)HAS_SNISSLError)F_GETFDF_SETFD FD_CLOEXECfcntlcCst|t}t|t|tBdS)z8Set the close-on-exec flag on the given file descriptor.N)r1r.r/r0)fdflagsr43/tmp/pip-target-onvjaxws/lib/python/pymongo/pool.py_set_non_inheritable_non_atomicFs r6cCsdS)z6Dummy function for platforms that don't provide fcntl.Nr4)r2r4r4r5r6Osx win32c Cs6z t||\}}t|WSttfy|YSwN)winreg QueryValueExintOSError ValueError)keynamedefaultvalue_r4r4r5_query^s  rFz2SYSTEM\CurrentControlSet\Services\Tcpip\ParametersZ KeepAliveTimeimZKeepAliveIntervalcCsHtttd}tttd}|tks|tkr"|tjd||fdSdS)NrG)min_WINDOWS_TCP_IDLE_MS_MAX_TCP_KEEPIDLE_WINDOWS_TCP_INTERVAL_MS_MAX_TCP_KEEPINTVLioctlsocketZSIO_KEEPALIVE_VALS)sockZidle_msZ interval_msr4r4r5_set_keepalive_timests rQcCsbtt|r/tt|}z|tj|}||kr!|tj||WdSWdStjy.YdSwdSr;)hasattrrOgetattr getsockopt IPPROTO_TCP setsockopterror)rPZ tcp_optionZ max_valueZsockoptrCr4r4r5_set_tcp_option|s  rXcCs(t|dtt|dtt|dtdS)N TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT)rXrKrM_MAX_TCP_KEEPCNTrPr4r4r5rQs  driver)rBZPyMongoversion _METADATAlinuxtyperB architectureosdarwin -rHjavacCsg|]}|r|qSr4r4).0partr4r4r5 srmPyPy.z (Python %s)platformz(%s)ZfooidnaaddressrW msg_prefixreturncCsx|\}}|durd|||f}nd||f}|r||}t|tjr't||t|tr7dt|vr7t||t||)z9Convert a socket.error to ConnectionFailure and raise it.Nz %s:%d: %sz%s: %s timed out) isinstancerOtimeoutrr-strr)rsrWrthostportmsgr4r4r5_raise_connection_failures     r}cCs|r|tnd}||Sr;)time monotonicwait) conditiondeadlinerxr4r4r5 _cond_waits rc@s$eZdZdZdZeeeddedddddde ddddfddZ e dd Z e d d Z e d d Ze ddZe ddZe ddZe ddZe ddZe ddZe ddZe ddZe ddZe d d!Ze d"d#Ze d$d%Ze d&d'Ze d(d)Ze d*d+Ze d,d-ZdS). PoolOptionsaYRead only connection pool options for a MongoClient. Should not be instantiated directly by application developers. Access a client's pool options via :attr:`~pymongo.client_options.ClientOptions.pool_options` instead:: pool_opts = client.options.pool_options pool_opts.max_pool_size pool_opts.min_pool_size )Z__max_pool_sizeZ__min_pool_sizeZ__max_idle_time_secondsZ__connect_timeoutZ__socket_timeoutZ__wait_queue_timeoutZ __ssl_contextZ__tls_allow_invalid_hostnamesZ__event_listenersZ __appnameZ__driverZ __metadataZ__compression_settingsZ__max_connectingZ__pause_enabledZ __server_apiZ__load_balancedZ __credentialsNFTcCs||_||_||_||_||_||_||_||_| |_| |_ | |_ | |_ | |_ ||_ ||_||_||_tt|_| rBd| i|jd<| r{| jrWdtdd| jf|jdd<| jrjdtdd| jf|jdd<| jr}dtd| jf|jd<dSdSdS)NrBZ applicationz%s|%sr^r_rq)_PoolOptions__max_pool_size_PoolOptions__min_pool_size#_PoolOptions__max_idle_time_seconds_PoolOptions__connect_timeout_PoolOptions__socket_timeout _PoolOptions__wait_queue_timeout_PoolOptions__ssl_context)_PoolOptions__tls_allow_invalid_hostnames_PoolOptions__event_listeners_PoolOptions__appname_PoolOptions__driver"_PoolOptions__compression_settings_PoolOptions__max_connecting_PoolOptions__pause_enabled_PoolOptions__server_api_PoolOptions__load_balanced_PoolOptions__credentialscopydeepcopyr`_PoolOptions__metadatarBr_rq)self max_pool_size min_pool_sizemax_idle_time_secondsconnect_timeoutsocket_timeoutwait_queue_timeout ssl_contexttls_allow_invalid_hostnamesZevent_listenersappnamer^compression_settingsmax_connecting pause_enabled server_api load_balanced credentialsr4r4r5__init__/sF     zPoolOptions.__init__cC|jS)z;A :class:`~pymongo.auth.MongoCredentials` instance or None.)rrr4r4r5 _credentialsnzPoolOptions._credentialscCsti}|jtkr |j|d<|jtkr|j|d<|jtkr"|jd|d<|jtkr.|jd|d<|jt kr8|j|d<|S)zqThe non-default options this pool was created with. Added for CMAP's :class:`PoolCreatedEvent`. Z maxPoolSizeZ minPoolSizerGZ maxIdleTimeMSZwaitQueueTimeoutMSZ maxConnecting) rrrrrrrrrr )roptsr4r4r5non_default_optionsss        zPoolOptions.non_default_optionscCr)aQThe 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. )rrr4r4r5rs zPoolOptions.max_pool_sizecCr)zThe minimum required number of concurrent connections that the pool will maintain to each connected server. Default is 0. )rrr4r4r5rzPoolOptions.min_pool_sizecCr)zgThe maximum number of concurrent connection creation attempts per pool. Defaults to 2. )rrr4r4r5rrzPoolOptions.max_connectingcCrr;)rrr4r4r5rzPoolOptions.pause_enabledcCr)zThe maximum number of seconds that a connection can remain idle in the pool before being removed and replaced. Defaults to `None` (no limit). )rrr4r4r5rsz!PoolOptions.max_idle_time_secondscCr)z>How long a connection can take to be opened before timing out.)rrr4r4r5rrzPoolOptions.connect_timeoutcCr)zBHow long a send or receive on a socket can take before timing out.)rrr4r4r5rrzPoolOptions.socket_timeoutcCr)zhHow long a thread will wait for a socket from the pool if the pool has no free sockets. )rrr4r4r5rrzPoolOptions.wait_queue_timeoutcCr)zAn SSLContext instance or None.)rrr4r4r5 _ssl_contextrzPoolOptions._ssl_contextcCr)z If True skip ssl.match_hostname.)rrr4r4r5rrz'PoolOptions.tls_allow_invalid_hostnamescCr)z2An instance of pymongo.monitoring._EventListeners.)rrr4r4r5_event_listenersrzPoolOptions._event_listenerscCr)zAThe application name, for sending with hello in server handshake.)rrr4r4r5rrzPoolOptions.appnamecCr)z=Driver name and version, for sending with hello in handshake.)rrr4r4r5r^rzPoolOptions.drivercCrr;)rrr4r4r5_compression_settingsrz!PoolOptions._compression_settingscCs |jS)zCA dict of metadata about the application, driver, os, and platform.)rrrr4r4r5metadatas zPoolOptions.metadatacCr)z'A pymongo.server_api.ServerApi or None.)rrr4r4r5rrzPoolOptions.server_apicCr)z6True if this Pool is configured in load balanced mode.)rrr4r4r5rrzPoolOptions.load_balanced)__name__ __module__ __qualname____doc__ __slots__rrrrr rpropertyrrrrrrrrrrrrrrr^rrrrr4r4r4r5r sv  ?                  rc@s(eZdZddZddZeddZdS)_CancellationContextcCs d|_dS)NF _cancelledrr4r4r5r z_CancellationContext.__init__cCs d|_dS)zCancel this context.TNrrr4r4r5cancels z_CancellationContext.cancelcCr)zWas cancel called?rrr4r4r5 cancelledrz_CancellationContext.cancelledN)rrrrrrrr4r4r4r5rs rc@s(eZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ejeddddddddddddfddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Z d9d:Z!d;d<Z"d=d>Z#d?d@Z$dAdBZ%dS)C SocketInfozStore 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 cCst||_||_||_||_t|_d|_t |_ d|_ d|_ t|_t|_t|_t|_d|_d|_d|_d|_|jj|_|j|_|jj|_d|_ t!|_"d|_#d|_$|j%|_&|j&'|_(d|_)d|_*|j+skt,|_*|j|_d|_-d|_.d|_/d|_0d|_1|jj2|_3d|_4dS)NFg)5weakrefrefpool_refrPrsidsetZauthedclosedr~rlast_checkin_timeperformed_handshake is_writablermax_wire_versionr max_bson_sizermax_message_sizermax_write_batch_sizesupports_sessionshello_ok is_mongosop_msg_enabledrr listenersenabled_for_cmaprrcompression_contextr+socket_checkernegotiated_mechsauth_ctxgenpool_gen get_overall generationreadycancel_context handshaker more_to_come service_id pinned_txn pinned_cursoractiver last_timeout connect_rtt)rrPpoolrsrr4r4r5rsL       zSocketInfo.__init__cCs$||jkrdS||_|j|dS)z?Cache last timeout to avoid duplicate calls to sock.settimeout.N)rrP settimeout)rrxr4r4r5set_socket_timeout5s zSocketInfo.set_socket_timeoutcCst}|dur|js||jjdSt}|dur|j}||}|dkr=d|dd|d}t|dd|dd|j |durIt |d|d<|||S) Nrz5operation would exceed time limit, remaining timeout:z.5fz <= network round trip time:2okerrmsgcoderGZ maxTimeMS) r remainingrrrrZget_rttrrrr>)rclientcmdrxZrttZ max_time_msrr4r4r5 apply_timeout<s$ zSocketInfo.apply_timeoutcCd|_|jrJdSNT)rrrr4r4r5pin_txnTzSocketInfo.pin_txncCrr)rrrr4r4r5 pin_cursorXrzSocketInfo.pin_cursorcCs*|}|r ||dS|tjdSr;)r return_socket close_socketr%STALE)rrr4r4r5unpin\szSocketInfo.unpincCs>|jjs |js |jjrd|_ttjdfgSttjdfdgS)NTrH)ZhelloOkT) rrrrrrr#ZCMDZ LEGACY_CMDrr4r4r5 hello_cmdcszSocketInfo.hello_cmdcCs|dddSr;)_hellorr4r4r5hellolzSocketInfo.helloc Cs(|}|j }d}|r'd|_|jj|d<|jr|jj|d<|jjr&d|d<n|durF||d<t|d|d<d}|jjrF| |jj||sP|durP||d <|jj }|rw|j d krh|j rh|j d |j |d <tj|}|rv||d <nd}|rt} |jd|d|d} |rt| |_t| |d} | j|_| j|_| j|_| j|_| j|_| jdu|_| j|_| jt j!t j"t j#t j$t j%fv|_&| jt j'k|_(| jt j)k|_*|r|jr|j+| j} | |_,d|_-|r| j.|_/|r|0| |1r||_2|jjr| j3st4d| j3|_3|j56|j3|_7| S)NFTr compressionZ loadBalancedZtopologyVersionrGZmaxAwaitTimeMSz $clusterTimeDEFAULTrpZsaslSupportedMechsZspeculativeAuthenticateZadmin)publish_eventsexhaust_allowed) awaitablez`Driver attempted to initialize in load balancing mode, but the server does not support this mode)8rrrrrZ compressorsrr>rrrZ mechanismusernamesourcer Z _AuthContextZfrom_credentialsZspeculate_commandr~rr&rr"rrrrrZlogical_session_timeout_minutesrrZ server_typer*Z RSPrimaryZ RSSecondaryZ RSArbiterZRSOtherZRSGhostZis_replZ StandaloneZ is_standaloneZMongosrZget_compression_contextrrZsasl_supported_mechsrparse_responseZspeculate_succeededrrrrgetr) rZ cluster_timeZtopology_versionZheartbeat_frequencyrZperforming_handshakercredsrstartdocrctxr4r4r5ros          zSocketInfo._hellocCs4|d}|j|_|}|d}t||j|SNr)r'rZunpack_responser _check_command_responser)rreplyZ unpacked_docsZ response_docr4r4r5 _next_replys zSocketInfo._next_replyTNFcCs || | t| |} t|tst|}|dus#|js#| dus#td||| r2| || ||| || | |r>|j nd}|oE|j }|j rN| |z t ||||j||| | |||j||j|| | |j|j ||||dWSttfyxty}z ||WYd}~dSd}~ww)aExecute 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 - `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 - `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. Nz3Collation is unsupported for unacknowledged writes.)parse_write_concern_error collationZcompression_ctxZ use_op_msgunacknowledged user_fieldsr write_concern)validate_sessionr rwrrZ acknowledgedradd_server_apiZ _apply_tosend_cluster_timerr_raise_if_not_writabler&rrsrrrr BaseExceptionr})rZdbnamespecZread_preference codec_optionscheckZallowable_errorsZ read_concernrrrsessionrZretryable_writerrrrrrWr4r4r5r&sZ )     zSocketInfo.commandc Csj|jdur||jkrtd||jfz |j|WdSty4}z ||WYd}~dSd}~ww)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.)rrrPsendallrr})rmessage max_doc_sizerWr4r4r5 send_messageszSocketInfo.send_messagec CsBzt|||jWSty }z ||WYd}~dSd}~ww)zzReceive a raw BSON message or raise ConnectionFailure. If any exception is raised, the socket is closed. N)r'rrr})r request_idrWr4r4r5r',s zSocketInfo.receive_messagecCs$|r|jstddddddSdS)z^Raise NotPrimaryError on unacknowledged write if this socket is not writable. z not primaryri{'rN)rr)rrr4r4r5r6s z!SocketInfo._raise_if_not_writablecCs|d|||dS)zSend unack OP_MSG. Can raise ConnectionFailure or InvalidDocument. :Parameters: - `msg`: bytes, an OP_MSG message. - `max_doc_size`: size in bytes of the largest document in `msg`. TN)rr#)rr|r"r4r4r5 unack_write>s zSocketInfo.unack_writecCs2||d||}||}t||j|S)zSend "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#r'Zcommand_responser rr)rr$r|rrresultr4r4r5 write_commandJs  zSocketInfo.write_commandcCsH|js |jj}|rt||d|_|jr"|j|j|j dSdSdS)zhAuthenticate to the server if needed. Can raise ConnectionFailure or OperationFailure. TN) rrrr authenticaterrZpublish_connection_readyrsr)rr r4r4r5r([s zSocketInfo.authenticatecCs|r |j|ur tddSdS)zValidate this session before use with client. Raises error if the client is not the one that created the session. z9Can only use session with the MongoClient that started itN)Z_clientr)rrrr4r4r5rjs  zSocketInfo.validate_sessioncCs<|jrdS||r|jr|j|j|j|dSdSdS)z$Close this connection with a reason.N)r _close_socketrrpublish_connection_closedrsr)rreasonr4r4r5rss  zSocketInfo.close_socketcCsF|jrdSd|_|jr|jz|jWdSty"YdSw)zClose this connection.NT)rrrrPclose Exceptionrr4r4r5r){s  zSocketInfo._close_socketcCs|j|jS)z?Return True if we know socket has been closed, False otherwise.)r socket_closedrPrr4r4r5r.zSocketInfo.socket_closedcCs|r |||dSdS)zAdd $clusterTime.N)Z_send_cluster_time)rr&rrr4r4r5rszSocketInfo.send_cluster_timecCs|jjr t||jjdSdS)zAdd server_api parameters.N)rrr))rr&r4r4r5rszSocketInfo.add_server_apicCst|_dSr;r~rrrr4r4r5update_last_checkin_timerz#SocketInfo.update_last_checkin_timecCs ||_dSr;)r)rrr4r4r5update_is_writablerzSocketInfo.update_is_writablecCst|jS)z9Seconds since this socket was last checked into its pool.r0rr4r4r5idle_time_secondsr/zSocketInfo.idle_time_secondscCs>|jrd}ntj}||t|tttfrt|j |dSr;) rr%ERRORrrwIOErrorr?r-r}rs)rrWr+r4r4r5r}s z$SocketInfo._raise_connection_failurecCs |j|jkSr;r]rotherr4r4r5__eq__s zSocketInfo.__eq__cCs ||k Sr;r4r6r4r4r5__ne__rzSocketInfo.__ne__cCs t|jSr;)hashrPrr4r4r5__hash__rzSocketInfo.__hash__cCs"dt|j|jr dp dt|fS)NzSocketInfo(%s)%s at %sz CLOSED)reprrPrrrr4r4r5__repr__s  zSocketInfo.__repr__)&rrrrrrrrrrrrrrr(ZPRIMARYrr&r#r'rr%r'r(rrr)r.rrr1r2r3r}r8r9r;r>r4r4r4r5rs^ 0 K  Z    rc Cs|\}}|dr4ttdstdttj}t|z|||WStjy3| wtj }tj rA|dkrAtj }d}t |||tjD]}|\}} } } } zt|| ttddB| }Wntjyut|| | }Ynwt|z:|tjtjdt} | dur|j} n | dkrtd || |tjtjd t||| |WStjy}z |}| WYd}~qLd}~ww|dur|td ) zGiven (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.sockAF_UNIXz-UNIX-sockets are not supported on this system localhostN SOCK_CLOEXECrrHrvTzgetaddrinfo failed)endswithrRrOrr?r6filenoconnectrWr,AF_INEThas_ipv6 AF_UNSPEC getaddrinfo SOCK_STREAMrSrVrU TCP_NODELAYrrrrxr SOL_SOCKET SO_KEEPALIVErQ)rsoptionsrzr{rPfamilyerrresafsocktypeprotodummysarxer4r4r5_create_connectionsZ           rWc Cst||}|j}|durm|d}ztr|j||d}n||}Wn*ty-|tttfyK}z|t ||dWYd}~nd}~ww|j rm|j sm|j smz t j||dWn tyl|w||j|S)zGiven (host, port) and PoolOptions, return a configured socket. Can raise socket.error, ConnectionFailure, or _CertificateError. Sets socket's SSL and timeout options. Nr)server_hostnamezSSL handshake failed: )hostname)rWrr, wrap_socketr!r,r5r?r-r} verify_modecheck_hostnamersslmatch_hostname getpeercertrr)rsrMrPrrzexcr4r4r5_configured_sockets>     rac@seZdZdZdS)_PoolClosedErrorzZInternal error raised when a thread tries to get a connection from a closed pool. N)rrrrr4r4r4r5rbAsrbc@s4eZdZddZddZddZddZd d Zd S) _PoolGenerationcCstt|_d|_dSr) collections defaultdictr> _generations _generationrr4r4r5rJs  z_PoolGeneration.__init__cCs|dur|jS|j|S)z,Get the generation for the given service_id.Nrgrfrrr4r4r5r Ps z_PoolGeneration.getcCr)z"Get the Pool's overall generation.)rgrr4r4r5rVrz_PoolGeneration.get_overallcCsN|jd7_|dur|jD] }|j|d7<qdS|j|d7<dS)z2Increment the generation for the given service_id.rHNrhrir4r4r5incZs  z_PoolGeneration.inccCs|||kS)z?Return if the given generation for a given service_id is stale.)r rrrr4r4r5stalecr/z_PoolGeneration.staleN)rrrrr rrjrlr4r4r4r5rcIs  rcc@seZdZdZdZdZdS) PoolStaterHrnrhN)rrrPAUSEDREADYCLOSEDr4r4r4r5rmhsrmc@seZdZd(ddZddZeddZd)d d Zd d Zd*d dZ ddZ ddZ ddZ ddZ d*ddZejd*ddZddZd*ddZdd Zd!d"Zd#efd$d%Zd&d'ZdS)+PoolTcCs |jrtj|_ntj|_d|_t|_t |_ d|_ d|_ d|_t|_t|_||_||_||_|joA|jjduoA|jjj|_t |j |_d|_|jj|_|jsZtd|_t |j |_|jj|_ d|_!|jrw|jj"|j|jj#d|_$t%|_&d|_'d|_(dS)z :Parameters: - `address`: a (hostname, port) tuple - `options`: a PoolOptions instance - `handshake`: whether to call hello for each new SocketInfo rHrNinf))rrmrnstatero_check_interval_secondsrddequesockets threadingLocklockactive_socketsnext_connection_idrrcrrdgetpidpidrsrrrr Condition size_condrequestsrfloat_max_connecting_condr_max_connecting_pendingZpublish_pool_createdroperation_countr_Pool__pinned_socketsncursorsntxns)rrsrMrr4r4r5rqsF           z Pool.__init__cCsv|j.|jtjkr!tj|_|jr)|jj|jWddSWddSWddS1s4wYdSr;) ryrsrmrorrrZpublish_pool_readyrsrr4r4r5rs "z Pool.readycCs |jtjkSr;)rsrmrprr4r4r5rs z Pool.closedNc Cs|j}|j|jr WddS|jjr%|r%|jjs%|jtj}|_|j |t }|j |kr=||_ d|_ d|_|durK|jt}|_n#t}t}|jD]} | j|krc|| qV|| qV|}||_|rttj|_|j|jWdn1swY|jj} |r|D]} | tjq|jr| |jdSdS|tjkr|jr| j|j|d|D]} | tjqdS)Nr)r) rsrrrrrrmrnrrjrdr|r}rzrrvrdrurappendrpr notify_allrrr% POOL_CLOSEDrZpublish_pool_closedrsZpublish_pool_clearedr) rr,pauser old_stateZnewpidrvdiscardZkeep sock_inforr4r4r5_resetsP        z Pool._resetcCsJ||_|j|jD]}||jq WddS1swYdS)zXUpdates the is_writable attribute on all sockets currently in the Pool. N)rryrvr2)rr_socketr4r4r5r2s  "zPool.update_is_writablecCs|jd|ddS)NF)r,rrrir4r4r5resetz Pool.resetcCs|jddddS)NF)r,rrrr4r4r5reset_without_pauserzPool.reset_without_pausecCs|jdddS)NT)r,rrr4r4r5r,sz Pool.closecCs|j||Sr;)rrlrkr4r4r5stale_generationrzPool.stale_generationcCs0|j|jtjkr WddSWdn1swY|jjdurb|j/|jrS|jd|jjkrS|j}| t j |jrS|jd|jjks:Wdn1s]wY |j 4t |j|j|jjkr| WddS|j|jjkr WddS|jd7_Wdn1swYd}z-|jb|j|jkr WdW|r|j|jd8_|jWdn1swY|j |jd8_|j WddS1swYdS|jd7_d}Wdn 1swY|}|jj|j|krx| t j WdW|rU|j|jd8_|jWdn 1sPwY|j |jd8_|j WddS1sqwYdS|j|Wdn 1swYW|r|j|jd8_|jWdn 1swY|j |jd8_|j Wdn 1swYnD|r|j|jd8_|jWdn 1swY|j |jd8_|j Wdw1swYwqc)zRemoves stale sockets then adds new ones if pool is too small and has not been reset. The `reference_generation` argument specifies the `generation` at the point in time this operation was requested on the pool. NrjTrHF)ryrsrmrorrrvr3poprr%IDLErlenrzrrrrrnotifyrDrrr appendleft)rZreference_generationr incrementedr4r4r5remove_stale_socketss       "   $     zPool.remove_stale_socketsc Cs|j|j}|jd7_Wdn1swY|jj}|jr+||j|z t|j|j}Wn'ty[}z|jrH| |j|t j t |t ttfrVt|j|d}~wwt|||j|}z|jrp||j|_|ry|j|dd|W|Sty|t j w)zConnect to Mongo and return a new SocketInfo. Can raise ConnectionFailure. Note that the pool does not keep a reference to the socket -- you must call return_socket() when you're done with it. rHNF)Zcompleted_handshake)ryr{rrrZpublish_connection_createdrsrarr*r%r4rwr5r?r-r}rrrrZcontribute_socketr(r)rhandlerZconn_idrrPrWrr4r4r5rD<s@     z Pool.connectccsH|jj}|jr||j|j|d}|jr||j|jz|VWn'tyK|j p0|j }|r@t \}}}| |||sJ|jrJ||w|j rr|j|j||jd7_WddS1skwYdS|j r|j|j||jd7_WddS1swYdS|jr||dSdS)aGet 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() as socket_info: socket_info.send_message(msg) data = socket_info.receive_message(op_code, request_id) Can raise ConnectionFailure or OperationFailure. :Parameters: - `handler` (optional): A _MongoClientErrorHandler. rrHN)rrrZ$publish_connection_check_out_startedrs _get_socketZpublish_connection_checked_outrrrrsysexc_infohandlerrryraddrr)rrrrpinnedexc_typeexc_valrEr4r4r5 get_sockeths>         " "zPool.get_socketcCsB|jtjkr|jr|r|jj|jtj t |jt ddSdS)Nzconnection pool paused) rsrmrorrr#publish_connection_check_out_failedrsr$ CONN_ERRORr}r)r emit_eventr4r4r5_raise_if_not_readys  zPool._raise_if_not_readycCs|jtkr ||jr|jr|jj|j t j t d|j |jd7_Wdn1s4wYtrBt}n|jjrOt|jj}nd}|j<|jdd|j|jkst|j|sv|j|jkrr|j||jdd|j|jkra|jd7_Wdn1swYd}d}d}z|j |jd7_d}Wdn1swY|dur|jY|jdd|js|j|j kst|j|s|js|j|j kr|jd}||jdd|js|j|j krz|j!}Wnt"y|jd7_YnwWdn 1s wY|r2|#|r1d}qnJz(|j$|d}W|j|jd8_|jWdn 1sUwYn!|j|jd8_|jWdw1svwYw|dusWnMt%y|r|&t'j(|j|jd8_|r|jd8_|jWdn 1swY|jr|s|jj|j t j)wd|_*|S)z8Get or create a SocketInfo. Can raise ConnectionFailure.z?Attempted to check out a connection from closed connection poolrHNT)rFr)+r}rdr|rrrrrrrsr$rrbryrr get_timeoutZ get_deadlinerr~rrrrrrr_raise_wait_queue_timeoutrzrrvrrpopleft IndexError _perishedrDrrr%r4rr)rrrrrZ emitted_eventr4r4r5rs                     zPool._get_socketcCs|j}|j}d|_d|_d|_|j||jj}|jr$||j |j |j t kr0|nR|jr:|tjnH|jrK|jrJ||j |j tjn7|j,||j|jr^|tjn|||j|j||j Wdn1s}wY|j!6|r|j"d8_"n |r|j#d8_#|j$d8_$|j%d8_%|j&d8_&|j! WddS1swYdS)zReturn the socket to the pool, or if it's closed discard it. :Parameters: - `sock_info`: The socket to check into the pool. FNrH)'rrrrrrrrZpublish_connection_checked_inrsrr}rdr|rrrr%rr*r4ryrrrrr1r2rrvrrrrrrrrzr)rrZtxncursorrr4r4r5rsL        "zPool.return_socketcCs|}|jjdur||jjkr|tjdS|jdur3d|jks'||jkr3|r3|tjdS| |j |j rC|tj dSdS)aReturn True and close the connection if it is "perished". 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, or if the socket's generation is outdated. 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. NTrF) r3rrrr%rrtr.r4rrrr)rrr3r4r4r5r8s&      zPool._perishedrucCsz|jj}|jr||jtjtp|jj }|jj r3|j |j |j }td|jj|j |j ||ftd|jj|f)NzTimeout waiting for connection from the connection pool. maxPoolSize: %s, connections in use by cursors: %s, connections in use by transactions: %s, connections in use by other operations: %s, timeout: %sz\Timed out while checking out a connection from connection pool. maxPoolSize: %s, timeout: %s)rrrrrsr$TIMEOUTrrrrrzrrr r)rrrxZ other_opsr4r4r5r\s.  zPool._raise_wait_queue_timeoutcCs|jD]}|dqdSr;)rvr)rrr4r4r5__del__ws  z Pool.__del__)T)TNr;)rrrrrrrrr2rrr,rrrD contextlibcontextmanagerrrrrrrrrr4r4r4r5rqps* C  /  8, 4 b1$ rqr;)}rdrrrdrqrOr]rrwr~rtypingrrrZbsonrZbson.sonrZpymongorrr r Zpymongo.client_sessionr Zpymongo.commonr r rrrrrrrrZpymongo.errorsrrrrrrrrrrr r!Z pymongo.hellor"r#Zpymongo.monitoringr$r%Zpymongo.networkr&r'Zpymongo.read_preferencesr(Zpymongo.server_apir)Zpymongo.server_typer*Zpymongo.socket_checkerr+Zpymongo.ssl_supportr,r-r1r.r/r0r6 ImportErrorrKrMr\_winregr<rFOpenKeyHKEY_LOCAL_MACHINErArJrLr?rQrXr`ry__annotations__ startswithsystem_namemachinereleasemac_verjoin win32_verjava_ver_verZ_arch system_aliasr_Z_aliasedpython_implementationmappypy_version_info version_infoencoder-r}robjectrrrrWrarbrcrmrqr4r4r4r5s$    08                                     aUG-