~fk `UddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZddlmZddlmZmZmZmZmZmZddlmZmZmZdd lmZmZmZmZdd l m!Z!dd l"m#Z#m$Z$dd l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-dd l.m/Z/ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7e2rddl8Z8dZ9dZ:dZ;dZZ?eeeeefe@d<e2reZAneZAGddZBGddZCGddZDGddeDZEGddeEZFGdd eDZGd!ZHd"ZIeJeKeKeIeIeLeJeJeIeKd# ZMd$ZNGd%d&ZOGd'd(eOZPy))N)abstractmethod)chain)EmptyFull LifoQueue)time)AnyCallableListOptionalTypeUnion)parse_qsunquoteurlparse)Encoder_HiredisParser _RESP2Parser _RESP3Parser) NoBackoff)CredentialProvider"UsernamePasswordCredentialProvider)AuthenticationError$AuthenticationWrongNumberOfArgsErrorChildDeadlockedErrorConnectionError DataError RedisError ResponseError TimeoutError)Retry)CRYPTOGRAPHY_AVAILABLEHIREDIS_AVAILABLEHIREDIS_PACK_AVAILABLE SSL_AVAILABLEformat_error_messageget_lib_version str_if_bytes*$s  DefaultParserceZdZdefdZy)HiredisRespSerializerargscg}t|dtr1t|djj |ddz}n)d|dvr"t|dj |ddz} |j t j||S#t$r3tj\}}}t|j|wxYw2Pack a series of arguments into the Redis protocolrrN ) isinstancestrtupleencodesplitappendhiredis pack_command TypeErrorsysexc_inforwith_traceback)selfr1output_value tracebacks Y/var/lib/jenkins/workspace/mettalog/venv/lib/python3.12/site-packages/redis/connection.pypackzHiredisRespSerializer.pack;s d1gs #a)//12T!"X=D T!W_a)DH4D = MM'..t4 5   ="%,,. AuiE"11)< < =s 1$B)>)@(KL++ t{{D)CSJD M) -c:. ~~:s:'='='?J d# c" ~~"J..0   !*4  d r,returnN)rIrJrKrSrHrLr,rGrNrNLs +r,rNc*eZdZdZdddddedddeddddeddddd dfd ed ee d ee d ee de de de de dededee dee dee dee de e dfdeegdfdeedeedeegdff&dZdZedZd Zd!Zd"Zd#Zd$Zd%Zed&Zed'Zd(Zd)Zd*Zd+Zd,Z d-Z!d6d/Z"d0Z#d7d1Z$ d8d.dd2d3Z%d4Z&d5Z'y)9AbstractConnectionz0Manages communication to and from a Redis serverrNFutf-8strictizredis-pyr-dbpasswordsocket_timeoutsocket_connect_timeoutretry_on_timeoutencodingencoding_errorsdecode_responsessocket_read_sizehealth_check_interval client_namelib_name lib_versionusernameretryredis_connect_funccredential_providerprotocolcommand_packerc|s|r | tdtj|_||_| |_||_||_||_||_ ||_ ||_ ||}||_ ||_ |turg}|r|jt ||_|s|rR|t%t'd|_nt+j,||_|j(j/|nt%t'd|_| |_d|_||_t7||| |_d|_| |_|j?| g|_ d|_! tE|}|dks|dkDr tMd ||_'|jQ||_)y#tF$r tH}YDtJ$r tMdwxYw#dks|dkDr tMd ||_'wxYw) a2 Initialize a new Connection. To specify a retry policy for specific errors, first set `retry_on_error` to a list of the error/s to retry on, then set `retry` to a valid `Retry` object. To retry on TimeoutError, `retry_on_timeout` can also be set to `True`. Nz'username' and 'password' cannot be passed along with 'credential_provider'. Please provide only one of the following arguments: 1. 'password' and (optional) 'username' 2. 'credential_provider'rripzprotocol must be an integerr-zprotocol must be either 2 or 3)*rosgetpidpidrfrprqrrrvrgrsrhrirjSENTINELr;r!retry_on_errorr"rrtcopydeepcopyupdate_supported_errorsronext_health_checkrurencoder_sock_socket_read_size set_parser_connect_callbacksrQintr>DEFAULT_RESP_VERSION ValueErrorrrw_construct_command_packer_command_packer)rBrfrgrhrirjrrkrlrm parser_classrnrorprqrrrsrtrurvrwrxps rGrSzAbstractConnection.__init__s> &9&E+  99;&  &#6     , ! )%3 "&<# 0 X %N   ! !, /, N}"9;2 "]]51 JJ . .~ >y{A.DJ%:"!""4x:JK  !1  %"$" H A 1uA%&FGGDM#==nM %$A A!"?@ @ A1uA%&FGGDMs$! FG.G0GGG%c dj|jDcgc] \}}|d|c}}}d|jjd|jjd|dScc}}w)N,=<.()>)rV repr_pieces __class__rJrI)rBkv repr_argss rG__repr__zAbstractConnection.__repr__sjHHT5E5E5GHTQ1QCjHI 4>>,,-Qt~~/F/F.Gq SUVVIsA, cyrPrLrBs rGrzAbstractConnection.repr_pieces r,cD |jy#t$rYywxYwrP) disconnect Exceptionrs rG__del__zAbstractConnection.__del__s#  OO    s  c~||Str tSt|j|jj SrP)r%r0rNrQrr9)rBpackers rGrz,AbstractConnection._construct_command_packers6  M #(* *'(;(;T\\=P=PQ Qr,ctj|}||jvr|jj|yy)a^ Register a callback to be called when the connection is established either initially or reconnected. This allows listeners to issue commands that are ephemeral to the connection, for example pub/sub subscription or key tracking. The callback must be a _method_ and will be kept as a weak reference. N)weakref WeakMethodrr;)rBcallbackwms rGregister_connect_callbackz,AbstractConnection.register_connect_callbacks;   ) T,, ,  # # * *2 . -r,c |jjtj|y#t$rYywxYw)z De-register a previously registered callback. It will no-longer receive notifications on connection events. Calling this is not required when the listener goes away, since the callbacks are kept as weak methods. N)rremoverrr)rBrs rGderegister_connect_callbackz.AbstractConnection.deregister_connect_callbacks8    # # * *7+=+=h+G H   s .1 ==c4||j|_y)z Creates a new instance of parser_class with socket size: _socket_read_size and assigns it to the parser for the connection :param parser_class: The required parser class )rnN)r_parser)rBrs rGrzAbstractConnection.set_parsers $T5K5KL r,c<jry jjfdfd}|_ jjnjjDcgc] }|s |c}_ jD]}|}|s |y#tj$r t dt $r}tj|d}~wwxYw#t$rjwxYwcc}w)z5Connects to the Redis server if not already connectedNc$jSrP)_connectrsrGz,AbstractConnection.connect..s  r,c&j|SrPr)errorrBs rGrz,AbstractConnection.connect..stu7Mr,zTimeout connecting to server)rrtcall_with_retrysockettimeoutr!OSErrorr_error_messageru on_connectrrr)rBsockerefrs` rGconnectzAbstractConnection.connects ::  :::--')MD  &&.!''-372I2I"S3SU3"S**CuH+-~~ ?=> > :!$"5"5a"89 9 :  OO   #Ts."B3.C;6 DD3&C8C33C8;DcyrPrLrs rGrzAbstractConnection._connect3rr,cyrPrLrs rG _host_errorzAbstractConnection._host_error7rr,c6t|j|SrP)r'r)rB exceptions rGrz!AbstractConnection._error_message;s#D$4$4$6 BBr,c|jj||j}d}|js|js |jr>|jxs t |j|j}|j }|r|jdvrt|jtrK|jt|j|j_ |jj|t|dk(rd|dg}|jd|jdg||j}n(|r@|jdg|dd i |j}t#|d k7rt%d |jdvrt|jtrK|jt|j|j_ |jj||jd|j|j}|j'd|jk7r)|j'd|jk7r t)d|j*rD|jdd|j*t#|jd k7r t)d |j,r.|jddd|j,|j |j0r.|jddd|j0|j|j2rD|jd|j2t#|jd k7r t)dyy#t $r+|jd|d d |j}YIwxYw#t.$rYwxYw#t.$rYwxYw)z=Initialize the connection, authenticate and select a databaseN)r-2rdefaultrHELLOAUTH check_healthFrOKzInvalid Username or PasswordsprotoprotozInvalid RESP versionCLIENTSETNAMEzError setting client nameSETINFOzLIB-NAMEzLIB-VERSELECTzInvalid Database)rrrvrsrgrget_credentialsrwr6rrrEXCEPTION_CLASSESrX send_command read_responserr)rgetrrprqr rrrf)rBparser auth_args cred_providerresponse auth_responses rGrzAbstractConnection.on_connect>sG %  # # ((T5dmmT]]S &557I h6$,, 5 -171I1I . ''-9~"& ! 5 D  gt}}f Iy I))+H  D  f Ey Eu E 5 $ 2 2 4 M*d2)*HII]]( *$,, 5 -171I1I . ''-   gt}} 5))+H X&$--7LL)T]]:%&<==      h 43C3C DD..01T9%&ABB }}!!(Iz4==Q""$ !!(Iy$BRBRS""$ 77   h 0D..01T9%&899: a8 5 !!&)B-e!L $ 2 2 4  5J      s6 N:N=;:O 0N:9N:= O O  OOcP|jj|j}d|_|ytj|j k(r |j tj |jy#ttf$rY#wxYw#t$rYywxYw)z!Disconnects from the Redis serverN) r on_disconnectrr{r|r}shutdownr SHUT_RDWRrr>close)rBr1 conn_socks rGrzAbstractConnection.disconnects ""$JJ     99;$(( " ""6#3#34  OO  Y'      s$B3BBB B%$B%cx|jddt|jdk7r tdy)z Send PING, expect PONG in returnPINGFrPONGz#Bad response from PING health checkN)rr)rrrs rG _send_pingzAbstractConnection._send_pings< &u5 **, - 7!"GH H 8r,c$|jy)z Function to call when PING failsNr)rBrs rG _ping_failedzAbstractConnection._ping_failed  r,c|jrIt|jkDr1|jj |j |j yyy)z3Check the health of the connection with a PING/PONGN)rorrrtrrrrs rGrzAbstractConnection.check_healthsA  % %$&43I3I*I JJ & &t8I8I J+J %r,TcN|js|j|r|j t|tr|g}|D]}|jj |y#t j$r|jtdt$ro}|jt|jdk(rd|jd}}n|jd}|jd}td|d|dd}~wt$r|jwxYw) z2Send an already packed command to the Redis serverzTimeout writing to socketrUNKNOWNrzError z while writing to socket. rN)rrrr6r7sendallrrrr!rrXr1r BaseException)rBcommandritemrerrnoerrmsgs rGsend_packed_commandz&AbstractConnection.send_packed_commandszz LLN      '3'") ""4( ~~ < OO :; ; W OO 166{a )166!9vq !F5'1KF8ST"UV V  OO    s5A&&6D$A*DD$cx|j|jj||jddy)z+Pack and send a command to the Redis serverrTrN)rrrHr)rBr1kwargss rGrzAbstractConnection.send_commands9   %D % %t ,ND9 ! r,c|j}|s|j|j} |jj |S#t $r0}|j td|d|jd}~wwxYw)z8Poll the socket to see if there's data that can be read.Error while reading from z: N) rrrrcan_readrrrr1)rBrr host_errorrs rGrzAbstractConnection.can_readsyzz LLN%%'  V<<((1 1 V OO !$=j\AFF8"TU U VsA B+A??B)disconnect_on_error push_requestc\|j} |jdvr$ts|jj ||}n|jj |}|jrt|jz|_t!|t"r ||S#t j $r!|r|jtd|t$r2}|r|jtd|d|jd}~wt$r|r|jwxYw#~wxYw)z0Read the response from a previously sent command)3rz)disable_decodingr)rzTimeout reading from rz : N)rrwr$rrrrrr!rrr1rrorrr6r )rBrrrrrrs rGrz AbstractConnection.read_responses(%%'  }}(1B<<55%5L6 <<55GW5X&  % %%)Vd.H.H%HD " h . 5~~ E"!!6zlCD D "!!+J<3qvvhG  #!   s$ABD(;D%-D D%(D+c4|jj|S)r4)rrH)rBr1s rGr=zAbstractConnection.pack_commands(t##(($//r,cg}g}d}|j}|D]}|jj|D]}t|}||kDs||kDst |t r*|r$|j tj|d}g}||kDst |t r|j |y|j |||z }|r$|j tj||S)z.Pack multiple commands into the Redis protocolr) rQrrHrXr6r[r;rUrV) rBcommandsrCpieces buffer_lengthrRcmdchunkchunklens rG pack_commandsz AbstractConnection.pack_commands!s ++ C2--22C8u:!M1-/!%4 innV&<=$%MFm+z%/LMM%(MM%(!X-M!9&  MM)..0 1 r,T)r)F)(rIrJrK__doc__r~r.r(rr r7floatboolrr r rrSrrrrrrrrrrrrrrrrrrrrrr=r rLr,rGrcrcs66"&*.26!&'!&" %%&%)",%4%6"&"&;?<@"#7;-WN WN3-WN! WN !) WN  WNWNWNWNWN #WNc]WN3-WN c]!WN"3-#WN$S$Y%WN&%Xb$h%78'WN(&&89)WN*3-+WN,!"d(!34-WNrW   R / M!F    CX:t(I K >  V ,! ,\0r,rcc@eZdZdZ dfd ZdZdZdZxZS) Connectionz4Manages TCP communication to and from a Redis serverc ||_t||_||_|xsi|_||_t |di|yNrL)hostrportsocket_keepalivesocket_keepalive_options socket_typesuperrS)rBrrrrrrrs rGrSzConnection.__init__CsD I 0(@(FB%& "6"r,cd|jfd|jfd|jfg}|jr|j d|jf|S)Nrrrfrp)rrrfrpr;rBrs rGrzConnection.repr_piecesSsM499% ':T477OL    MM=$*:*:; < r,c@d}tj|j|j|jtj D]}|\}}}}}d} tj|||}|j tjtjd|jrr|j tjtjd|jjD]&\} } |j tj| | (|j|j|j!||j|j"|cS||t%d#t$$r} | }||j'Yd} ~ Qd} ~ wwxYw)zCreate a TCP socket connectionNrz)socket.getaddrinfo returned an empty list)r getaddrinforrr SOCK_STREAM setsockopt IPPROTO_TCP TCP_NODELAYr SOL_SOCKET SO_KEEPALIVEritems settimeoutrirrhrr) rBerrresfamilysocktyper canonnamesocket_addressrrrrDs rGrzConnection._connectYs\ %% IItyy$"2"2F4F4F CBE >FHeYD !}}VXu= 2 2F4F4FJ((OOF$5$5v7J7JAN $ = = C C E1(:(:AqA!F ; ;< ^, 3 34 1 > ?IABB !#JJL !sD E55 F>FFc8|jd|jS)N:)rrrs rGrzConnection._host_errors))Adii[))r,) localhostiFNr rIrJrKr rSrrr __classcell__rs@rGrr@s-: !% #  'CR*r,rcJeZdZdZ dfd ZfdZxZS) SSLConnectionzManages SSL connections to and from the Redis server(s). This class extends the Connection class, adding SSL functionality, and making use of ssl.SSLContext (https://docs.python.org/3/library/ssl.html#ssl.SSLContext) c ts td||_||_|tj }nWt |trGtj tjtjd}||vrtd|||}||_ ||_ ||_ ||_ ||_||_| |_| |_| |_| |_| |_||_t-|\di|y)aConstructor Args: ssl_keyfile: Path to an ssl private key. Defaults to None. ssl_certfile: Path to an ssl certificate. Defaults to None. ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required). Defaults to "required". ssl_ca_certs: The path to a file of concatenated CA certificates in PEM format. Defaults to None. ssl_ca_data: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates. ssl_check_hostname: If set, match the hostname during the SSL handshake. Defaults to False. ssl_ca_path: The path to a directory containing several CA certificates in PEM format. Defaults to None. ssl_password: Password for unlocking an encrypted private key. Defaults to None. ssl_validate_ocsp: If set, perform a full ocsp validation (i.e not a stapled verification) ssl_validate_ocsp_stapled: If set, perform a validation on a stapled ocsp response ssl_ocsp_context: A fully initialized OpenSSL.SSL.Context object to be used in verifying the ssl_ocsp_expected_cert ssl_ocsp_expected_cert: A PEM armoured string containing the expected certificate to be returned from the ocsp verification service. ssl_min_version: The lowest supported SSL version. It affects the supported SSL versions of the SSLContext. None leaves the default provided by ssl module. ssl_ciphers: A string listing the ciphers that are allowed to be used. Defaults to None, which means that the default ciphers are used. See https://docs.python.org/3/library/ssl.html#ssl.SSLContext.set_ciphers for more information. Raises: RedisError z$Python wasn't built with SSL supportN)noneoptionalrequiredz+Invalid SSL Certificate Requirements Flag: rL)r&rkeyfilecertfilessl CERT_NONEr6r7 CERT_OPTIONAL CERT_REQUIRED cert_reqsca_certsca_dataca_pathcheck_hostnamecertificate_passwordssl_validate_ocspssl_validate_ocsp_stapledssl_ocsp_contextssl_ocsp_expected_certssl_min_version ssl_ciphersrrS)rB ssl_keyfile ssl_certfile ssl_cert_reqs ssl_ca_certs ssl_ca_datassl_check_hostname ssl_ca_path ssl_passwordrBrCrDrErFrGr CERT_REQSrs rGrSzSSLConnection.__init__sPCD D" $  MMM  s + ----I I- A-Q&m4M&$ " " 0$0!!2)B& 0&<#.& "6"r,cJt |}tj}|j|_|j |_|js |jr2|j|j|j|j|j|j |j2|j|j|j|j|j|j|_|j"r|j%|j"|j'||j(}|j*durt,dur t/d|j0r|j*r t/d|j0r+d dl}d d lm}|j8f|j:j=|j:j>}|jA|j|jC|jn |j8}|jE||jF|j:jI|tKjJ}|jM|jO|j(|jPf|jS|jU|S|j*durRt,rLd d lm+}|||j(|jP|j} | jYr|St[d |S)z Wrap the socket with SSL support)r7r6rgN)cafilecapathcadata)server_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.rr)ocsp_staple_verifier) OCSPVerifierzocsp validation error).rrr8create_default_contextr@r< verify_moder7r6load_cert_chainrAr=r?r>load_verify_locationsrFminimum_versionrG set_ciphers wrap_socketrrBr#rrCOpenSSLocsprVrDSSLContext SSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackrErr request_ocsprr do_handshakerrWis_validr) rBrcontextsslsockr_rV staple_ctxconrWors rGrzSSLConnection._connectsw!,,.!%!4!4"nn ==DLL  # # 22 $  MM %||'||'  ) )}}T\\$,, *     +&*&:&:G #       0 0 1%%dDII%F  ! !T ).D.M=> >  ) )d.D.D   ) )  2$$,$[[001J1JK // >..t||<!22  / /$d&A&A  ++((V]]_EC     KKDII. /     LLNN  ! !T ).D *WdiiDMMJAzz|%&=>>r,)NNr5NNFNNFFNNNN)rIrJrKr rSrr.r/s@rGr1r1sG  "'#F#PEEr,r1c6eZdZdZdfd ZdZdZdZxZS)UnixDomainSocketConnectionz4Manages UDS communication to and from a Redis serverc @t|di|||_||_yr)rrSpathrh)rBrrrhrrs rGrSz#UnixDomainSocketConnection.__init__s" "6" ,r,cd|jfd|jfg}|jr|jd|jf|S)Nrrrfrp)rrrfrpr;rs rGrz&UnixDomainSocketConnection.repr_pieces$sB499%dgg7    MM=$*:*:; < r,c tjtjtj}|j|j|j |j |j|j|S)z&Create a Unix domain socket connection)rAF_UNIXrr#rirrrrh)rBrs rGrz#UnixDomainSocketConnection._connect*sU}}V^^V-?-?@ 334 TYY ++, r,c|jSrP)rrrs rGrz&UnixDomainSocketConnection._host_error2s yyr,)Nr-r/s@rGrprps:-  r,rp)0FFALSENNOcv||dk(ryt|tr|jtvryt |S)NrwF)r6r7upper FALSE_STRINGSr )rEs rGto_boolr9s4 } %%++-="@ ;r,) rfrhrirrjrmax_connectionsrorMrcB|jds-|jds|jds tdt|}i}t|jj D]N\}}|s t |dkDst|d}tj|}|r ||||<J|||<P|jrt|j|d<|jrt|j|d <|jd k(r/|jrt|j|d <t|d <|S|j rt|j |d <|j"rt%|j"|d<|jr6d|vr2 t%t|jj'dd|d<|jdk(r t*|d <|S#ttf$rtd|dwxYw#t(tf$rYMwxYw)Nzredis://z rediss://zunix://zRRedis URL must specify one of the following schemes (redis://, rediss://, unix://)rzInvalid value for `z` in connection URL.rsrgunixrrconnection_classrrrf/rwrediss) startswithrrrqueryr"rXrURL_QUERY_ARGUMENT_PARSERSrr>rsrgschemerrrphostnamerrreplaceAttributeErrorr1)urlrnamerErs rG parse_urlrOs z" >>+ & >>) $ 5  3-C F *002 e SZ!^E!H%E/33D9FW#)%=F4L %t 3 ||$S\\2z ||$S\\2z zzV 88$SXX.F6N%?!"& M! <<$S\\2F6N 88 ]F6N 88F* "7388#4#<# - `rediss://` creates a SSL wrapped TCP socket connection. See more at: - ``unix://``: creates a Unix Domain Socket connection. The username, password, hostname, path and all querystring values are passed through urllib.parse.unquote in order to replace any percent-encoded values with their corresponding characters. There are several ways to specify a database number. The first value found will be used: 1. A ``db`` querystring option, e.g. redis://localhost?db=0 2. If using the redis:// or rediss:// schemes, the path argument of the url, e.g. redis://localhost/0 3. A ``db`` keyword argument to this function. If none of these options are specified, the default db=0 is used. All querystring options are cast to their appropriate Python types. Boolean arguments can be specified with string values "True"/"False" or "Yes"/"No". Values that cannot be properly cast cause a ``ValueError`` to be raised. Once parsed, the querystring arguments and keyword arguments are passed to the ``ConnectionPool``'s class initializer. In the case of conflicting arguments, querystring arguments always win. rrL)rupdate)clsrr url_optionss rGfrom_urlzConnectionPool.from_urls?R n  '.45G.HK* + k"}V}r,Nrc |xsd}t|tr|dkr td||_||_||_t j|_|jy)Nlrz,"max_connections" must be a positive integer) r6rrrconnection_kwargsr threadingLock _fork_lockreset)rBrrrs rGrSzConnectionPool.__init__s\ *2U/3/?Q3FKL L 0!2.$..* r,rac dt|jdt|jdt|jdi|j dS)NrrrrrL)typerJrIreprrrrs rGrzConnectionPool.__repr__sVT %%&aT (;(;'<*T**DT-C-CDEFb J r,ctj|_d|_g|_t |_tj|_ y)Nr) rr_lock_created_connections_available_connectionsset_in_use_connectionsr{r|r}rs rGrzConnectionPool.resets9^^% $%!&(##&5 99;r,cf|jtjk7rq|jj d}|st  |jtjk7r|j |jjyy#|jjwxYw)N)r)r}r{r|racquirerrrelease)rBacquireds rG _checkpidzConnectionPool._checkpidsF 88ryy{ "..q.9H** *88ryy{*JJL'') #'')s 1BB0 command_namercN|j|j5 |jj}|j j|ddd j |jr td |S#t$r|j }YnwxYw#1swYXxYw#ttf$r?|j|j|jr tdY|SwxYw#t$r|jwxYw)zGet a connection from the poolNConnection has dataConnection not ready)rrrpop IndexErrormake_connectionraddrrrrrrrrBrkeysoptions connections rGget_connectionzConnectionPool.get_connection&s'  ZZ 5 4!88<<>   $ $ ( ( 4  5      B&&()*?@@)3 4!113  4 5 5"$W- B%%'""$&&()*@AA) B   LL $   sXB+B B+D.B7 B(%B+'B((B++B47A DDDDD$c|j}t|jdd|jdd|jddS)z,Return an encoder based on encoding settingsrkrdrlrermF)rkrlrm)rrr)rBrs rG get_encoderzConnectionPool.get_encoderGsF''ZZ G4"JJ'8(C#ZZ(:EB  r,c|j|jk\r td|xjdz c_|jdi|jS)zCreate a new connectionzToo many connectionsrrL)rrrrrrs rGrzConnectionPool.make_connectionPsO  $ $(<(< <!"89 9 !!Q&!$t$$>t'='=>>r,rcv|j|j5 |jj||j |r|j j|n/|xjdzc_|j dddy dddy#t$rYqwxYw#1swYyxYw)z(Releases the connection back to the poolrN) rrrrKeyErrorowns_connectionrr;rrrBrs rGrzConnectionPool.releaseWs  ZZ  ((// ; ##J/++22:> ))Q.)%%'!  ?      s.B/B AB/ B,)B/+B,,B//B8c4|j|jk(SrP)r}rs rGrzConnectionPool.owns_connectionls~~))r,inuse_connectionsc|j|j5|r!t|j|j}n |j}|D]}|j  dddy#1swYyxYw)z Disconnects connections in the pool If ``inuse_connections`` is True, disconnect connections that are current in use, potentially by other threads. Otherwise only disconnect connections that are idle in the pool. N)rrrrrr)rBr connectionsrs rGrzConnectionPool.disconnectosk  ZZ ( #//1I1I #99 ) %%'* ( ( (s AA..A7c$|jy)z-Close the pool, disconnecting all connectionsNrrs rGrzConnectionPool.closerr,c|jjd|i|jD] }||_ |jD] }||_ y)Nrt)rrrrtr)rBrtconns rG set_retryzConnectionPool.set_retrysI %%w&67//DDJ0,,DDJ-r,r`)rar)rrraNr )rtr"raN)rIrJrKr  classmethodrrr rrSr7rrrrrrrrrr rrrrLr,rGrrs ..d$)-"#2 3* "-*^3\B W ?**,*3*(D(D((r,rcJeZdZdZddeeffd ZdZdZdZ dZ d Z xZ S) BlockingConnectionPoola Thread-safe blocking connection pool:: >>> from redis.client import Redis >>> client = Redis(connection_pool=BlockingConnectionPool()) It performs the same function as the default :py:class:`~redis.ConnectionPool` implementation, in that, it maintains a pool of reusable connections that can be shared by multiple redis clients (safely across threads if required). The difference is that, in the event that a client tries to get a connection from the pool when all of connections are in use, rather than raising a :py:class:`~redis.ConnectionError` (as the default :py:class:`~redis.ConnectionPool` implementation does), it makes the client wait ("blocks") for a specified number of seconds until a connection becomes available. Use ``max_connections`` to increase / decrease the pool size:: >>> pool = BlockingConnectionPool(max_connections=10) Use ``timeout`` to tell it either how many seconds to wait for a connection to become available, or to block forever: >>> # Block forever. >>> pool = BlockingConnectionPool(timeout=None) >>> # Raise a ``ConnectionError`` after five seconds if a connection is >>> # not available. >>> pool = BlockingConnectionPool(timeout=5) 2c F||_||_t| d||d|y)N)rrrL) queue_classrrrS)rBrrrrrrs rGrSzBlockingConnectionPool.__init__s6'   -+   r,c|j|j|_ |jjd#t$rYnwxYwg|_t j|_yrP) rrpool put_nowaitr _connectionsr{r|r}rs rGrzBlockingConnectionPool.resetsf$$T%9%9:   $$T*   99;s? A  A ct|jdi|j}|jj||S)zMake a fresh connection.rL)rrrr;rs rGrz&BlockingConnectionPool.make_connections7*T**DT-C-CD    ,r,c |jd} |jjd|j}||j } |j |jr t d |S#t$r t dwxYw#t tf$r?|j|j|jr t dY|SwxYw#t$r|j|wxYw)a7 Get a connection, blocking for ``self.timeout`` until a connection is available from the pool. If the connection returned is ``None`` then creates a new connection. Because we use a last-in first-out queue, the existing connections (having been returned to the pool after the initial ``None`` values were added) will be returned before ``None`` values. This means we only create new connections when we need to, i.e.: the actual number of connections will only increase in response to demand. NT)blockrzNo connection available.rr) rrrrrrrrrrrrrrs rGrz%BlockingConnectionPool.get_connections   >T4<<HJ  --/J      B&&()*?@@)= >""<= = >($W- B%%'""$&&()*@AA) B   LL $  s6'A=C&B=BA C#C&"C##C&&Dc|j|j|s,|j|jj dy |jj |y#t $rYywxYw)z)Releases the connection back to the pool.N)rrrrrrrs rGrzBlockingConnectionPool.releasesj ##J/  ! ! # II  &   II  ,   sA++ A76A7cf|j|jD]}|jy)z(Disconnects all connections in the pool.N)rrrrs rGrz!BlockingConnectionPool.disconnect(s( ++J  ! ! #,r,) rIrJrKr rrrSrrrrrr.r/s@rGrrs6F#  0 2h*$r,r)Qrr{rr8r?rrabcr itertoolsrqueuerrrrtypingr r r r r r urllib.parserrr_parsersrrrrbackoffr credentialsrr exceptionsrrrrrrr r!rtr"utilsr#r$r%r&r'r(r)r<rWr\rYrUrobjectr~__annotations__r.r0rNrcrr1rprrrr listrrrrrLr,rGrsT ((==44IIO         8E, nDEFF"M M$00f~~BC*#C*LSJSl!34/  # ! 6rDDN]$^]$r,