b ddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z ddl m Z ddlmZmZmZddlmZddlmZddlmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%dd l&m'Z'dd l(m)Z)m*Z*m+Z+ ddl,Z,d Z-e/ej`iZ1e-r7e2e,d rde1e,jf<de1e,jh<nde1e,jj<e6e1joZ8e*r=ddl9Z9ee9jtZ;e;edk\Zd Z?e=sd Z?dZ@dZAdZBdZCdZDeEZFdZGdZHdZIdZJGddZKGddZLGdd ZMGd!d"eLZNGd#d$eLZOe*reOZPneNZPGd%d&ZQGd'd(eQZRGd)d*eQZSd+ZTd,ZUeVeWeWeUeUeXeVeVeUd- ZYd.ZZGd/d0Z[Gd1d2e[Z\y#e.$rd Z-YDwxYw)3N)chain)EmptyFull LifoQueue)time)parse_qsunquoteurlparse)Version) NoBackoff)AuthenticationError$AuthenticationWrongNumberOfArgsErrorBusyLoadingErrorChildDeadlockedErrorConnectionError DataErrorExecAbortErrorInvalidResponse ModuleErrorNoPermissionError NoScriptError ReadOnlyError RedisError ResponseError TimeoutError)Retry)CRYPTOGRAPHY_AVAILABLEHIREDIS_AVAILABLE str_if_bytesTFSSLWantReadErrorz0.1.3z0.1.4z1.0.0*$s zConnection closed by server.z:Error loading the extension. Please check the server logs.z5Error unloading module: no such module with that namez/Error unloading module: operation not possible.z[Error unloading module: the module exports one or more module-side data types, can't unloadc$eZdZdZdZdZddZy)Encoderz=Encode strings to bytes-like and decode bytes-like to stringsc.||_||_||_yNencodingencoding_errorsdecode_responses)selfr*r+r,s 2/usr/lib/python3/dist-packages/redis/connection.py__init__zEncoder.__init__Xs  . 0r$ct|ttfr|St|tr t dt|t t frt|j}n4t|ts$t|j}t d|dt|tr&|j|j|j}|S)z=Return a bytestring or bytes-like representation of the valuezNInvalid input of type: 'bool'. Convert to a bytes, string, int or float first.zInvalid input of type: 'z2'. Convert to a bytes, string, int or float first.) isinstancebytes memoryviewboolrintfloatreprencodestrtype__name__r*r+)r-valuetypenames r.r8zEncoder.encode]s eeZ0 1L t $5 U| ,K&&(EE3'E{++H*8*5BC  eS !LL0D0DEE r$c|js|rVt|tr|j}t|tr&|j |j |j}|S)z:Return a unicode string from the bytes-like representation)r,r1r3tobytesr2decoder*r+)r-r<forces r.r@zEncoder.decodetsK  E%, %' T]]D4H4HI r$NF)r; __module__ __qualname____doc__r/r8r@r$r.r&r&UsC1 .r$r&cJeZdZdededededeeeeee ee ei e e e eeedZdZy) BaseParserzmax number of clients reachedz(Client sent AUTH, but no password is setzinvalid passwordz,wrong number of arguments for 'auth' commandz,wrong number of arguments for 'AUTH' command)ERR EXECABORTLOADINGNOSCRIPTREADONLYNOAUTHNOPERMc|jdd}||jvrN|t|dzd}|j|}t|tr|j |t }||St |S)zParse an error response rN)splitEXCEPTION_CLASSESlenr1dictgetr)r-response error_codeexception_classs r. parse_errorzBaseParser.parse_errors{^^C(+ // /J! 3 56H"44Z@O/40"1"5"5h "N"8, ,X&&r$N)r;rCrDrr rMODULE_LOAD_ERRORrMODULE_EXPORTS_DATA_TYPES_ERRORNO_SUCH_MODULE_ERROR MODULE_UNLOAD_NOT_POSSIBLE_ERRORrrrrrrTr[rFr$r.rHrH~s_ ,_ 68K  3 !"F !"F { +[ + ,k "$#!!%#/4 'r$rHcNeZdZdZedZdedfdZdZdZ dZ d Z d Z y) SocketBufferc|||_||_||_tj|_d|_d|_yNr)_socksocket_read_sizesocket_timeoutioBytesIO_buffer bytes_written bytes_read)r-socketrerfs r.r/zSocketBuffer.__init__s5 0,zz| r$c4|j|jz Sr()rjrkr-s r.lengthzSocketBuffer.lengths!!DOO33r$NTc|j}|j}|j}|j|jd}|t u} |r|j | |jj|} t| trt| dk(rtt|j| t| } |xj| z c_|| z }|||kDr |r|j |jyy#tj $r.|r t#dY|r|j |jyyt$$rq} t&j)| j*d} |s2| j,| k(r#Yd} ~ |r|j |jyytd| j.d} ~ wwxYw#|r|j |jwwxYwNrTzTimeout reading from socketFz!Error while reading from socket: )rdreriseekrjSENTINEL settimeoutrecvr1r2rUrSERVER_CLOSED_CONNECTION_ERRORwriterfrltimeoutrNONBLOCKING_EXCEPTIONS#NONBLOCKING_EXCEPTION_ERROR_NUMBERSrW __class__errnoargs) r-roryraise_on_timeoutsockrebufmarkercustom_timeoutdata data_lengthexalloweds r._read_from_socketzSocketBuffer._read_from_socketszz00ll ##$ 0 5(zz'78dE*s4yA~)*HII $!$i ""k1"+%%&6/ 3 34~~ "#@AA 3 34& Q :==bllBOG#G(; 3 34"$EbggY"OP P Q 3 34s= BD F>%GF> 1F9>G!F99F>>G G!cVt|jxs|j|dS)NFryr)r4rorr-rys r.can_readzSocketBuffer.can_reads/DKK  D$:$:e%;%  r$c~|dz}||jkDr|j||jz |jj|j|jj |}|xjt |z c_|j|jk(r|j|ddS)Nr!) rorrirsrkreadrUrjpurge)r-rors r.rzSocketBuffer.reads! DKK   " "6DKK#7 8 $//*||  ( 3t9$ ??d00 0 JJLCRyr$c|j}|j|j|j}|j t sQ|j |j|j|j}|j t sQ|xjt|z c_|j|jk(r|j|ddS)Nr) rirsrkreadlineendswithSYM_CRLFrrUrjr)r-rrs r.rzSocketBuffer.readlinesll !||~--)  " " $ HHT__ %<<>D --) 3t9$ ??d00 0 JJLCRyr$c|jjd|jjd|_d|_yrc)rirstruncaterjrkrns r.rzSocketBuffer.purges3 ! r$c |j|jjd|_d|_y#t$rYwxYwr()rriclose Exceptionrdrns r.rzSocketBuffer.close sF  JJL LL         s*; AA) r;rCrDr/propertyrortrrrrrrrFr$r.rarasD44(,XPT'5R "& r$rac6eZdZdZdZdZdZdZdZd dZ y) PythonParserzPlain Python parsing classc<||_d|_d|_d|_yr()reencoderrdrir-res r.r/zPythonParser.__init__s 0   r$cD |jy#t$rYywxYwr( on_disconnectrrns r.__del__zPythonParser.__del__$%          c|j|_t|j|j|j|_|j |_y)zCalled when the socket connectsN)rdrarerfrirr- connections r. on_connectzPythonParser.on_connect*sA%% # JJ--z/H/H  ")) r$czd|_|j!|jjd|_d|_y)z"Called when the socket disconnectsN)rdrirrrns r.rzPythonParser.on_disconnect2s1 << # LL   DL r$cT|jxr|jj|Sr()rirrs r.rzPythonParser.can_read:s ||> 5 5g >>r$c|jj}|stt|dd|dd}}|dvrt d||dk(r8|j dd}|j |}t|tr||S|dk(rn|d k(r t|}np|d k(r-t|}|d k(ry|jj|}n>|d k(r9t|}|d k(ryt|Dcgc]}|j| }}t|tr|dur|jj |}|Scc}w)NrR)-+:r#r"zProtocol Error: rutf-8replace)errorsrrr#rrr"disable_decodingF)rirrrwrr@r[r1r5rrange read_responser2r)r-rrawbyterXerrorrois r.rzPythonParser.read_response=s]ll##%!"@A ARa#ab'h 5 5!$4SG"<= = 4<wyAH$$X.E%1 L T\  T\8}H T\]F|||((0H T\]F|v""4D"EH h &+;u+D||**84H s1D=NrB) r;rCrDrEr/rrrrrrFr$r.rrs#   *?.r$rcBeZdZdZdZdZdZdZdZe dfdZ d d Z y ) HiredisParserz*Parser class for connections using Hirediscbts td||_trt ||_yy)NzHiredis is not installed)rrreHIREDIS_USE_BYTE_BUFFER bytearrayrirs r.r/zHiredisParser.__init__qs. 78 8 0 "$%56DL #r$cD |jy#t$rYywxYwr(rrns r.rzHiredisParser.__del__yrrc j|j|_|j|_t|jd}t s t |d<|jjr|jj|d<tr|jj|d<tjdi||_d|_y)N) protocolError replyErrorrr*rFrF)rdrf_socket_timeoutrr[ HIREDIS_SUPPORTS_CALLABLE_ERRORSrrr,r* HIREDIS_SUPPORTS_ENCODING_ERRORSr+hiredisReader_reader_next_response)r-rkwargss r.rzHiredisParser.on_connects%% )88#2$BRBRS0#0F<    . .!+!3!3!)>?!&%0CK14D)*HII !!&) 4 45~~ "#@AA 4 45& Q :==bllBOG#G(; 4 45"$EbggY"OP P Q 4 45s<C'D G=GG%1GG9GGG G9c|jstt|jdur|j}d|_|S|r|jj d}n|jj }|durM|j |r|jj d}n|jj }|durMt sxt|tr|j|jd}nIt|tr9|r7t|dtr$|j|djd|d<t|tr|t|tr|rt|dtr|d|S)NFr) rrrwrrrrr1rr[r~list)r-rrXs r.rzHiredisParser.read_responsesN||!"@A A   e +**H"'D O ||((/H||((*H%  ! ! #<<,,U3<<,,. %0(M2++HMM!,<=8T*x{M:"..x{/?/?/BC  h 0N x &8A;81+ r$NrB) r;rCrDrEr/rrrrrtrrrFr$r.rrns007 $ $ (0$#6J+r$rceZdZdZddddddddddeddded dddddfd Zd Zd Zd Z dZ dZ dZ dZ dZdZdZdZdZdZdZddZdZd dZd!dZdZdZy)" Connectionz4Manages TCP communication to and from a Redis server localhostirNFrstrictctj|_||_t ||_||_||_||_||_ ||_ |xs||_ ||_ |xsi|_ | |_| |_| t urg} | r| j#t$| |_| rR|t)t+d|_nt/j0||_|j,j3| nt)t+d|_||_d|_||_t;| | ||_d|_||_ |jC|g|_"d|_#y)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`. NrRrp)$osgetpidpidhostr5portdbusername client_namepasswordrfsocket_connect_timeoutsocket_keepalivesocket_keepalive_options socket_typeretry_on_timeoutrtappendrretry_on_errorrr retrycopydeepcopyupdate_supported_errorshealth_check_intervalnext_health_checkredis_connect_funcr&rrd_socket_read_size set_parser_connect_callbacks_buffer_cutoff)r-rrrrrfrrrrrrr*r+r, parser_classrerrrrrs r.r/zConnection.__init__s@>99; I   &  ,&<&N# 0(@(FB%& 0 X %N   ! !, /, }"9;2 "]]51 JJ . .~ >y{A.DJ%:"!""4x:JK  !1  %"$"r$c dj|jDcgc] \}}|d|c}}}|jjd|dScc}}w)N,=<>)join repr_piecesr|r;)r-kv repr_argss r.__repr__zConnection.__repr__@sVHHT5E5E5GHTQ1QCjHI ..))*!I;a88IsA cd|jfd|jfd|jfg}|jr|j d|jf|S)Nrrrr)rrrrrr-piecess r.rzConnection.repr_piecesDsM499% ':T477OL    MM=$*:*:; < r$cD |jy#t$rYywxYwr() disconnectrrns r.rzConnection.__del__Js#  OO    rc`|jjtj|yr()rrweakref WeakMethod)r-callbacks r.register_connect_callbackz$Connection.register_connect_callbackPs! &&w'9'9('CDr$cg|_yr()rrns r.clear_connect_callbacksz"Connection.clear_connect_callbacksSs "$r$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 )reN)r_parser)r-rs r.rzConnection.set_parserVs $T5K5KL r$cjry jjfdfd}|_ jjnjjD]}|}|s |y#tj$r t dt $r}tj|d}~wwxYw#t$rjwxYw)z5Connects to the Redis server if not already connectedNc$jSr()_connectrnsr.z$Connection.connect..ds  r$c&j|Sr(r )rr-s r.rz$Connection.connect..dstu7Mr$zTimeout connecting to server)rdrcall_with_retryrlryrOSErrorr_error_messagerrrr r)r-rerefr s` r.connectzConnection.connect^s ::  :::--')MD  &&.!''-** CuH )~~ ?=> > :!$"5"5a"89 9 :  OO   s""B .C &C2C  CC/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 connectionNrRz)socket.getaddrinfo returned an empty list)rl getaddrinforrr SOCK_STREAM setsockopt IPPROTO_TCP TCP_NODELAYr SOL_SOCKET SO_KEEPALIVEritemsrurrrfrr) r-errresfamilysocktypeproto canonnamesocket_addressrrr_s r.rzConnection._connectsg %% IItyy$"2"2F4F4F  !CBE >FHeYD !}}VXu= 2 2F4F4FJ((OOF$5$5v7J7JAN $ = = C C EB1(:(:AqAB ; ;< ^, 3 34 1 !> ?IABB !#JJL !sD E55 F>FFc t|jdk(r. d|jd|jd|jddS d|jdd |jd|jd |jdd S#t$rd|jdcYSwxYw#t$rd|jdcYSwxYw) NrRzError connecting to :z. r.zConnection Error: Error z connecting to . )rUr~rrAttributeErrorr- exceptions r.rzConnection._error_messages y~~ ! # @-dii[$))E"*+1..  @Y^^A./yyk499+R q0A/B!E " @+INN1,=+>?? @" @+INN1,=+>?? @s#,B)>)@(KL++ t||**D1 CSJD M) -c:. ~~:s:'='='?J d# c" ~~"J..0   ! 4  d r$cg}g}d}|j}|D]}|j|D]}t|}||kDs||kDst|tr(|j t j|d}g}||kDst|tr|j |w|j |||z }|r$|j t j||S)z.Pack multiple commands into the Redis protocolr)rrWrUr1r3rr_r) r-commandsrcr buffer_lengthrecmdchunkchunklens r. pack_commandszConnection.pack_commandsws ++  .C***C0 .u:!M1-/!%4MM).."89$%MFm+z%/LMM%(MM%(!X-M . .$  MM)..0 1 r$T)rrB)r;rCrDrErt DefaultParserr/rrrrrrrrrrr rJrLr;rUrArrrWrnrFr$r.rrs:  #!% "-D#L9  E%MB'CR@$%:N$I K 6 4+Zr$rcFeZdZdZ 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 tdt| di| ||_||_|t j}nWt|trGt jt jt jd}||vrtd|||}||_ ||_ ||_||_||_||_| |_| |_| |_| |_y)aeConstructor 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. Raises: RedisError z$Python wasn't built with SSL supportN)noneoptionalrequiredz+Invalid SSL Certificate Requirements Flag: rF) ssl_availablersuperr/keyfilecertfilessl CERT_NONEr1r9 CERT_OPTIONAL CERT_REQUIRED cert_reqsca_certsca_dataca_pathcheck_hostnamecertificate_passwordssl_validate_ocspssl_validate_ocsp_stapledssl_ocsp_contextssl_ocsp_expected_cert)r- ssl_keyfile ssl_certfile ssl_cert_reqs ssl_ca_certs ssl_ca_datassl_check_hostname ssl_ca_path ssl_passwordrrrrr CERT_REQSr|s r.r/zSSLConnection.__init__sHCD D "6"" $  MMM  s + ----I I- A-Q&m4M&$ " " 0$0!!2)B& 0&<#r$ct |}tj}|j|_|j |_|js |jr2|j|j|j|j|j|j |j2|j|j|j|j|j||j }|j"durt$dur t'd|j(r|j"r t'd|j(r+d dl}d d lm}|j0f|j2j5|j2j6}|j9|j|j;|jn |j0}|j=||j>|j2jA|tCjB}|jE|jG|j |jHf|jK|jM|S|j"durRt$rLd d lm'}|||j |jH|j} | jQr|StSd |S)z Wrap the socket with SSL support)rzryrN)cafilecapathcadata)server_hostnameTFzcryptography is not installed.zKEither an OCSP staple or pure OCSP connection must be validated - not both.rrR)ocsp_staple_verifier) OCSPVerifierzocsp validation error)*rxrr{create_default_contextrr verify_moderzryload_cert_chainrrrrload_verify_locations wrap_socketrrrrrOpenSSLocsprrSSLContext SSLv23_METHODuse_certificate_fileuse_privatekey_fileset_ocsp_client_callbackrrrl request_ocsprr do_handshakerEris_validr) r-rcontextsslsockrr staple_ctxconror|s r.rzSSLConnection._connectsHw!,,.!%!4!4"nn ==DLL  # # 22 $  MM %||'||'  ) )}}T\\$,, * %%dDII%F  ! !T ).D.M=> >  ) )d.D.D   ) )  2$$,$[[001J1JK // >..t||<!22  / /$d&A&A  ++((V]]_EC     KKDII. /     LLNN  ! !T ).D *WdiiDMMJAzz|%&=>>r$) NNrvNNFNNFFNN)r;rCrDrEr/r __classcell__r|s@r.rrrrsA  "'#A=FAAr$rrcFeZdZdddddddddeedddddfdZd Zd Zd Zy) UnixDomainSocketConnectionr9rNrrFrc~tj|_||_||_||_||_||_||_| |_ | turg} | r| jt| |_ |jrR|ttd|_nt#j$||_|j j'| nttd|_| |_d|_||_t/||||_d|_| |_|j7| g|_d|_y)aB Initialize a new UnixDomainSocketConnection. 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`. NrRrr)rrrpathrrrrrfrrtrrrrr rrrrrrrr&rrdrrrr)r-rrrrrfr*r+r,rrrrerrrrs r.r/z#UnixDomainSocketConnection.__init__#s499;   &  , 0 X %N   ! !, /,   }"9;2 "]]51 JJ . .~ >y{A.DJ%:"!""4x:JK  !1  %"$"r$cd|jfd|jfg}|jr|jd|jf|S)Nrrr)rrrrrs r.rz&UnixDomainSocketConnection.repr_pieces_sB499%dgg7    MM=$*:*:; < r$ctjtjtj}|j|j|j |j |S)z&Create a Unix domain socket connection)rlAF_UNIXr!rurfrr)r-rs r.rz#UnixDomainSocketConnection._connectesC}}V^^V-?-?@ ++, TYY r$ct|jdk(r d|jd|jddSd|jdd|jd|jddS)NrRz!Error connecting to unix socket: r4rr2r3z connecting to unix socket: )rUr~rr6s r.rz)UnixDomainSocketConnection._error_messagelsu y~~ ! #6tyykINNSTDUCVVWX X*++G99+R q 12!5 r$) r;rCrDrtrpr/rrrrFr$r.rr"sI  "#:#x  r$r)0FFALSENNOcv||dk(ryt|tr|jtvryt |S)Nr9F)r1r9upper FALSE_STRINGSr4)r<s r.to_boolr{s4 } %%++-="@ ;r$) rrfrrrrmax_connectionsrrct|}i}t|jjD]N\}}|s t |dkDst |d}t j|}|r ||||<J|||<P|jrt |j|d<|jrt |j|d<|jdk(r/|jrt |j|d<t|d<|S|jd vr|jrt |j|d <|j rt#|j |d <|jr6d |vr2 t#t |jj%d d|d <|jdk(r t(|d<|Std#ttf$rtd|dwxYw#t&tf$rYXwxYw)NrzInvalid value for `z` in connection URL.rrunixrconnection_class)redisredissrrr/r9rzRRedis URL must specify one of the following schemes (redis://, rediss://, unix://))r rqueryr'rUr URL_QUERY_ARGUMENT_PARSERSrW TypeError ValueErrorrrschemerrhostnamerr5rr5rr)urlrnamer<parsers r. parse_urlrs 3-C F *002 % e SZ!^E!H%E/33D9FW#)%=F4L %t  % ||$S\\2z ||$S\\2z zzV 88$SXX.F6N%?!"0 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. rrF)rupdate)clsrr url_optionss r.from_urlzConnectionPool.from_urls?R n  '.45G.HK* + k"}V}r$Nc |xsd}t|tr|dkr td||_||_||_t j|_|jy)Nlrz,"max_connections" must be a positive integer) r1r5rrconnection_kwargsr threadingLock _fork_lockreset)r-rrrs r.r/zConnectionPool.__init__s\*2U/3/?Q3FKL L 0!2.$..* r$c ~t|jdt|jdi|jdS)NrrrF)r:r;r7rrrns r.rzConnectionPool.__repr__sCDz""#*T**DT-C-CDEFa I r$ctj|_d|_g|_t |_tj|_ yrc) rr_lock_created_connections_available_connectionsset_in_use_connectionsrrrrns r.rzConnectionPool.resets9^^% $%!&(##&5 99;r$cf|jtjk7rq|jj d}|st  |jtjk7r|j |jjyy#|jjwxYw)N)ry)rrrracquirerrrelease)r-acquireds r. _checkpidzConnectionPool._checkpid0sF 88ryy{ "..q.9H** *88ryy{*JJL'') #'')s 1BB0cN|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_connectionraddrrrrr rQrr- command_namekeysoptionsrs r.get_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 settingsr*rr+rr,Fr))rr&rW)r-rs r. get_encoderzConnectionPool.get_encodersF''ZZ G4"JJ'8(C#ZZ(:EB  r$c|j|jk\r td|xjdz c_|jdi|jS)zCreate a new connectionzToo many connectionsrRrF)rrrrrrns r.rzConnectionPool.make_connectionsO  $ $(<(< <!"89 9 !!Q&!$t$$>t'='=>>r$cv|j|j5 |jj||j |r|j j|n/|xjdzc_|j dddy dddy#t$rYqwxYw#1swYyxYw)z(Releases the connection back to the poolrRN) rrrremoveKeyErrorowns_connectionrrrr rs r.rzConnectionPool.releases  ZZ  ((// ; ##J/++22:> ))Q.)%%'!  ?      s.B/B AB/ B,)B/+B,,B//B8c4|j|jk(Sr()rrs r.rzConnectionPool.owns_connections~~))r$c|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 )r-inuse_connections connectionsrs r.r zConnectionPool.disconnectsp  ZZ ( #//1I1I #99 ) ( %%' ( ( ( (s AA..A7ro)r;rCrDrE classmethodrrr/rrrrrrrrr rFr$r.rrsW ..b *4, "-*^B ?**(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)rrrF) queue_classryrxr/)r-rryrr rr|s r.r/zBlockingConnectionPool.__init__s6'   -+   r$c|j|j|_ |jjd#t$rYnwxYwg|_t j|_yr() r rpool put_nowaitr _connectionsrrrrns r.rzBlockingConnectionPool.resetsf$$T%9%9:   $$T*   99;s? A  A ct|jdi|j}|jj||S)zMake a fresh connection.rF)rrr rrs r.rz&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)blockryzNo connection available.rr) rr rWryrrrrrrr rQrrs r.rz%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)rrr r r rrs r.rzBlockingConnectionPool.releaseBsj ##J/  ! ! # II  &   II  ,   sA++ A76A7cf|j|jD]}|jy)z(Disconnects all connections in the pool.N)rr r rs r.r z!BlockingConnectionPool.disconnectWs- ++ $J  ! ! # $r$) r;rCrDrErrr/rrrrr rrs@r.rrs6F#  "0 2h*$r$r)]rr}rgrrlrr  itertoolsrqueuerrrr urllib.parserr r packaging.versionr redis.backoffr redis.exceptionsr rrrrrrrrrrrrrr redis.retryr redis.utilsrrrr{rw ImportErrorBlockingIOError EWOULDBLOCKr{hasattrr SSLWantWriteErrorSSLErrorr^rrzr __version__hiredis_versionrHIREDIS_SUPPORTS_BYTE_BUFFERrrr`rbrr_rwobjectrtr\r^r_r]r&rHrarrrprrrrrrr5r6rrrrrrFr$r.r%s@ ((44%#"OOM(78I8I&J#s&'DE+C,@,@AEF+C,A,AB<=+CLL9BGGIJg112O'6'':J'J$#2gg6F#F '6'':J'J$" '"'     !? 8SN#W  &&R$'$'NsslP:Pf@J@F!M M[[| JJJZSSl/  # ! 1hv(v(r^$^^$k,Ms<F<<GG