b ddlZddlZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z m Z mZmZddlmZddlmZmZmZmZddlmZddlmZmZmZddlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&ddl'm(Z(m)Z)dd l*m+Z+m,Z,dd l-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;dd lZ>m?Z?dd l@mAZAmBZBmCZCed eDde deedfZEdZFdedeeDeffdZGGddeZHGddee"e)ZIGddZJGddZKGddee"e)ZLeD]8ZMeMjddjZMeMdk(r)ePeLeMe$eM:Gdd ZQy)!N) AnyDequeDict GeneratorListMappingOptionalTypeTypeVarUnion)ResponseCallbackT) Connection DefaultParserEncoder parse_url)CommandsParser)EMPTY_RESPONSE NEVER_DECODE AbstractRedis) PIPELINE_BLOCKED_COMMANDSPRIMARYREPLICASLOT_IDAbstractRedisCluster LoadBalancerblock_pipeline_command get_node_nameparse_cluster_slots) READ_COMMANDSAsyncRedisClusterCommands)REDIS_CLUSTER_HASH_SLOTSkey_slot)AskErrorBusyLoadingErrorClusterCrossSlotErrorClusterDownError ClusterErrorConnectionError DataErrorMasterDownError MovedErrorRedisClusterException ResponseErrorSlotNotCoveredError TimeoutError TryAgainError)AnyKeyT EncodableTKeyT) dict_mergesafe_str str_if_bytes TargetNodesT ClusterNode) client_namedbdecode_responses encoder_classencodingencoding_errorshealth_check_interval parser_classpasswordredis_connect_funcretryretry_on_timeoutsocket_connect_timeoutsocket_keepalivesocket_keepalive_optionssocket_read_sizesocket_timeout socket_typeusernamekwargsreturnc h|jDcic]\}}|tvs||c}}Scc}}w)z0Remove unsupported or disabled keys from kwargs.)itemsCONNECTION_ALLOWED_KEYS)rLkvs 7/usr/lib/python3/dist-packages/redis/asyncio/cluster.pycleanup_kwargsrTRs,#\\^ LTQq4K/KAqD LL Ls..c @eZdZeej eeee e e dZy) ClusterParser)ASKTRYAGAINMOVED CLUSTERDOWN CROSSSLOT MASTERDOWNN) __name__ __module__ __qualname__r4rEXCEPTION_CLASSESr#r0r+r&r%r*rSrVrVWs-"''%+.)   rbrVceZdZdZedededdfdZdZ d:de ed e d e e d d e d e de de de ededdfdZ d;dZddZd>dZd?dZ d@de ed e e d e ede d fd!Z dAd"ed#e de d fd$Zd"e de fd%Z!de"fd&Z#de$ee effd'Z%d(ed)e&ddfd*Z'dd+d(ed,ed-e ede d fd.Z(d(ed,ede fd/Z)d0ede fd1Z*d0ede d fd2Z+d,e dedefd3Z,d4d d,e-e.e fdedefd5Z/ dBd6e ed7e edd8fd9Z0y)C RedisClustera Create a new RedisCluster client. Pass one of parameters: - `url` - `host` & `port` - `startup_nodes` | Use ``await`` :meth:`initialize` to find cluster nodes & create connections. | Use ``await`` :meth:`close` to disconnect connections & close client. Many commands support the target_nodes kwarg. It can be one of the :attr:`NODE_FLAGS`: - :attr:`PRIMARIES` - :attr:`REPLICAS` - :attr:`ALL_NODES` - :attr:`RANDOM` - :attr:`DEFAULT_NODE` Note: This client is not thread/process/fork safe. :param host: | Can be used to point to a startup node :param port: | Port used if **host** is provided :param startup_nodes: | :class:`~.ClusterNode` to used as a startup node :param cluster_error_retry_attempts: | Retry command execution attempts when encountering :class:`~.ClusterDownError` or :class:`~.ConnectionError` :param require_full_coverage: | When set to ``False``: the client will not require a full coverage of the slots. However, if not all slots are covered, and at least one node has ``cluster-require-full-coverage`` set to ``yes``, the server will throw a :class:`~.ClusterDownError` for some key-based commands. | When set to ``True``: all slots must be covered to construct the cluster client. If not all slots are covered, :class:`~.RedisClusterException` will be thrown. | See: https://redis.io/docs/manual/scaling/#redis-cluster-configuration-parameters :param reinitialize_steps: | Specifies the number of MOVED errors that need to occur before reinitializing the whole cluster topology. If a MOVED error occurs and the cluster does not need to be reinitialized on this current error handling, only the MOVED slot will be patched with the redirected node. To reinitialize the cluster on every MOVED error, set reinitialize_steps to 1. To avoid reinitializing the cluster on moved errors, set reinitialize_steps to 0. :param read_from_replicas: | Enable read from replicas in READONLY mode. You can read possibly stale data. When set to true, read commands will be assigned between the primary and its replications in a Round-Robin manner. :param url: | See :meth:`.from_url` :param kwargs: | Extra arguments that will be passed to the :class:`~redis.asyncio.connection.Connection` instances when created :raises RedisClusterException: if any arguments are invalid. Eg: - db kwarg - db != 0 in url - unix socket connection - none of host & url & startup_nodes were provided urlrLrMc |dd|i|S)a' Return a Redis client object configured from the given URL. For example:: redis://[[username]:[password]]@localhost:6379/0 rediss://[[username]:[password]]@localhost:6379/0 unix://[[username]:[password]]@/path/to/socket.sock?db=0 Three URL schemes are supported: - `redis://` creates a TCP socket connection. See more at: - `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 :class:`~redis.asyncio.connection.Connection` when created. In the case of conflicting arguments, querystring arguments always win. rerara)clsrerLs rSfrom_urlzRedisCluster.from_urlsT%s%f%%rb) _initialize_lockcluster_error_retry_attempts command_flagscommands_parserconnection_kwargsencoder node_flags nodes_managerread_from_replicasreinitialize_counterreinitialize_stepsresponse_callbacksresult_callbacksNhostport startup_nodesr8require_full_coveragerrrkrtc  x|sg}d| vr td|rft|} d| vr tdd| vr| ddk7r td| j| | jd}| jd|}n|r|s |s td |j| d <t di| x|_} |jjjx|_ | d <|r(|r&|jt||fi|j td||d |j |_t| jd d| jdd| jdd|_||_||_||_d|_t+|_|jj.j|_|jj2j|_|jj6j|_d|j8d<d|_t=j>|_ y)Nr:z4Argument 'db' is not possible to use in cluster modepathzFRedisCluster does not currently support Unix Domain Socket connectionsrz9A ``db`` querystring option can only be 0 in cluster moderwrxa5RedisCluster requires at least one node to discover the cluster. Please provide one of the followings: 1. host and port, for example: RedisCluster(host='localhost', port=6379) 2. list of startup nodes, for example: RedisCluster(startup_nodes=[ClusterNode('localhost', 6379), ClusterNode('localhost', 6378)])rBru)ryrzr=zutf-8r>strictr;FcNtt|jdfi|S)Nr)rlistvalues)cmdresrLs rSz'RedisCluster.__init__..:s'':  q !( %+( rb CLUSTER SLOTSTra)!r,rupdateget on_connectrTrn __class__RESPONSE_CALLBACKScopyruappendr8 NodesManagerrqrrorkrrrtrsrrm NODE_FLAGSrp COMMAND_FLAGSrlRESULT_CALLBACKSrvriasyncioLockrj) selfrwrxryrzrrrkrtrerL url_optionss rS__init__zRedisCluster.__init__s>M 6>'F  #C.K$+){"{4'8A'=+O MM+ &::f%D::fd+DdM'4 (,#$*8*B6*BB NN - - 2 2 4 5& #  D  T4!R4;Q;Q!R S) '"7 $$   JJz7 + JJ(( 3 JJ)5 1  -I)"4"4$%!-/..3388:!^^99>>@ $ ? ? D D F     \\^ rbc4K|jr|j4d{|jra |jjd{|jj|jj d{d|_dddd{|S|S77X7##t $rI|jjd{7|jjdd{7wxYw7c#1d{7swY|SxYww)zJGet all nodes from startup nodes & creates connections if not initialized.NFry)rirjrq initializerm default_node BaseExceptionclosers rSrzRedisCluster.initialize@s   zz  ## "00;;==="22== ..;;,1(   t  >)"0066888"0066GGG     sDB%D DB+B'6B+B) B+ DD D'B+)B++&C=C#C=5C86C==DDDD DDcZK|js~|j4d{|jsLd|_|jjd{|jjdd{dddd{yy7n7;77 #1d{7swYyxYww)z.Close all connections & client if initialized.NTry)rirjrqrrs rSrzRedisCluster.closeQszz D D'''+D$,,22444,,22?CCC  D D D  D5C  D D D DshB+BB+1BB"B7B8B< B+BB+BBB+B(B B($B+c>K|jd{S7wNrrs rS __aenter__zRedisCluster.__aenter__Z__&&&& c@K|jd{y7wr)rrexc_type exc_value tracebacks rS __aexit__zRedisCluster.__aexit__]sjjls c>|jjSrr __await__rs rSrzRedisCluster.__await__` **,,rbzUnclosed RedisCluster clientct|drl|js_tj|jd|t | ||jd}t jj|yyy#t$rYywxYw)Nri sourceclientmessage) hasattrriwarningswarn _DEL_MESSAGEResourceWarningrget_event_loopcall_exception_handler RuntimeError)rcontexts rS__del__zRedisCluster.__del__es 4 '0@0@ MMT../q9?SW X %)d6G6GH&&(??H 1A '    s2A:: BB connectioncK|jt|jd{|jrI|j dd{t |j d{dk7r tdyy7Z777w)NREADONLYOKzREADONLY command failed) set_parserrVrrr send_commandr6read_response_without_lockr()rrs rSrzRedisCluster.on_connectosm,##%%%  " " ))*5 5 5*"G"G"IIJdR%&?@@S # & 6Is3)B B$B BB -B .B B  B c\t|jjjS)zGet all nodes of the cluster.)rrq nodes_cacherrs rS get_nodeszRedisCluster.get_nodes}s"D&&2299;<<<Q( (/33sc"33 u:?')DE yy{1G$4s%BED=AE7D?/E?E target_nodescBt|txr||jvSr) isinstancestrrp)rr s rS _is_node_flagzRedisCluster._is_node_flag(s,,P1PPrbct|tr|}|St|tr|g}|St|trt|j }|St dt |)Nztarget_nodes type can be one of the following: node_flag (PRIMARIES, REPLICAS, RANDOM, ALL_NODES),ClusterNode, list, or dict. The passed type is )r rr8dictr TypeErrortype)rr nodess rS_parse_target_nodesz RedisCluster._parse_target_nodes+s lD ) E   k 2!NE  d +,,./E &'+<&8%9; rbc Kd}g}d}j}jdd}|r&j|sj|}d}d}t |D]K}j rj d{ |s+jd|id{}|stdd t|dk(r[j|dgid{} |jvr(j|||dj| ificS| cS|D cgc]} | j} } tjfd |Dd{} |jvr,j||tt!| | ficStt!| | cS7.77cc} w7e#t"$r1} t%| j&j(vr| }n| Yd} ~ d} ~ wwxYww) a| Execute a raw command on the appropriate cluster node or target_nodes. It will retry the command as specified by :attr:`cluster_error_retry_attempts` & then raise an exception. :param args: | Raw command args :param kwargs: - target_nodes: :attr:`NODE_FLAGS` or :class:`~.ClusterNode` or List[:class:`~.ClusterNode`] or Dict[Any, :class:`~.ClusterNode`] - Rest of the kwargs are passed to the Redis connection :raises RedisClusterException: if target_nodes is not provided & the command can't be mapped to a slot rFr NTrr!No targets were found to execute command onc3pK|]-}tjj|gi/ywr)r ensure_future_execute_command).0rrrLrs rS z/RedisCluster.execute_command..us@!%$11 5 5 5d LT LV Ls36)rkrr rrangerirrr,rrrvrrgatherrziprrrERRORS_ALLOW_RETRY)rrrLrr target_nodes_specifiedretry_attemptspassed_targets_retrrre exceptions``` rSexecute_commandzRedisCluster.execute_command?sG$q' !&::ND9 $"4"4^"D33NCL%) "N~&, Aoo''') -)>)>)>*)7*$L(3?v[Q|$) 5 5 5l1o W WPV WWC$"7"77=t44W=#l1o&:&:C%@ DJ J2>?$DII?D?#*>>)5 $F$"7"77=t44W=#T#dF*;%< @F  D& 122I, `]($X@! 7dnn???!"IG  sA>G=F1G= G F4!?G F7!7GG=GG=G#F96"GF>;GG=G+G=4G7G9G G: &G5/G=5G::G= target_nodecKdx}}d}|j}d}|dkDr|dz} |r.|j|}|jdd{d}nN|rL|j|d{} |jj | |j xr |dtv}d}|j|i|d{St1d 7z7`7#t$rttf$rG|dz }|dkrtjdd{7n|jd{7Yn4t$r{} |xjdz c_|j r=|j|j zdk(r!|jd{7d|_n| |j_d}Yd} ~ nd} ~ wt$$r3||jd z krtjd d{7Ynxt&$r-} t)| j*| j, }d}Yd} ~ nHd} ~ wt.$r9tjdd{7|jd{7wxYw|dkDrHw) NFrrrASKING?Trg?rwrxzTTL exhausted.)RedisClusterRequestTTLrr'rrqrrrrr$r(r/rsleeprr+rsrt_moved_exceptionr0r#rrwrxr&r') rr(rrLaskingmoved redirect_addrttlconnection_error_retry_counterrr%s rSrzRedisCluster._execute_commandsH )))*&Ag 1HC> "&----"HK%55h???"F"6!5!5t!<?-2L A: A$ A=4 .=DtM2DDd=1DL/ /#"#' BsmBsmBC= B - B).$$!%$ - $82:2#2W&tC#,>'?&4S4a A rbobjcXt|txr|j|jk(Sr)r r8r)rrVs rS__eq__zClusterNode.__eq__'s!#{+EDII0EErbzUnclosed ClusterNode objectc|jD]n}|jstj|jd|t | ||jd}t jj|yy#t$rYywxYw)Nrrr) rG is_connectedrrrrrrrr)rrrs rSrzClusterNode.__del__,s++ J&& (()4(3_T)-$:K:KLG**,CCGL $s 2A?? B  B cKtjd|jDddid{}td|Dd}|r|y7w)Nc3bK|]'}tj|j)ywrrr disconnect)rrs rSrz)ClusterNode.disconnect..<s,%%j&;&;&=>-/return_exceptionsTc3BK|]}t|ts|ywr)r  Exception)rrs rSrz)ClusterNode.disconnect..BsEC*S)*DCEs)rrrGnext)rr$excs rSr^zClusterNode.disconnect:s\NN"&"3"3 #   E3EtL I  s*A A A c|jrtt|jD]G}|jj}|jr|cS|jj |I|jjSt|j |jkr9|jdi|j}|j j ||Std)NzToo many connectionsra) rHrrpopleftrZrrGrJrIrnr()rr#rs rSacquire_connectionzClusterNode.acquire_connectionFs ::3tzz?+ .!ZZ//1 **%% !!*-  . ::%%' ' t  !D$8$8 8...H1G1GHJ    $ $Z 0 455rbrrrLcK t|vr|jdd{}n|jd{}||jvr|j||fi|S|S7C7,#t$rt|vr |tcYSwxYww)NT)disable_decoding)rrr-rru)rrrrLresponses rSparse_responsezClusterNode.parse_responseWs v%!+!F!F%)"G"",!F!F!HH d-- -34**73HGG GI 'n--  sGB A)A%A)A'A)&B %A)'A))BB BB rc6K|j}|j|j|dd{ |j||dfi|d{|jj |S7?7!#|jj |wxYww)NFr)rgsend_packed_command pack_commandrkrHr)rrrLrs rSr'zClusterNode.execute_commandls,,. ,,-DZ-D-Dd-KUSSS *,,,ZaKFKK JJ  j ) TL JJ  j )s83BA5BA9A7A9B7A99BBcK|j}|j|jd|jDdd{d}|jD];} |j||j dfi|j d{|_=|jj||S7m7*#t$r}||_d}Yd}~vd}~wwxYww)Nc34K|]}|jywr)r)rrs rSrz/ClusterNode.execute_pipeline..s$M#SXX$MsFrT) rgrm pack_commandsrFrkrrLresultrbrHr)rrr$rr%s rSexecute_pipelinezClusterNode.execute_pipelinezs,,. ,,  $ $$M9L9L$M Mu   && C #64#6#6 $/2zz$   *% %    sNACB6 C.B: B8 B: C8B:: C C CCCr=)r]r^r_rArCrr rr r rrrUrDrXrrr^rgrkr'rsrarbrSr8r8s I$&*$-7 :::c] :  : z* :!: :< # F#F$F1L  6J6"$/2>A * *3 *# *# *rbc eZdZdZ ddeddededdfdZ dd ee d ee d ee dedfd Z dd e e dfde e dfdeddfdZ ddZ dde deddfdZde dedfdZddZdde ddfdZy)r)r0rnrrread_load_balancerrzrryryr8rzrLrMNc |Dcic]}|j|c}|_||_||_d|_i|_i|_t|_d|_ ycc}wr) rryrzrnrrrrrur0)rryrzrLrs rSrzNodesManager.__init__s` ;HH$diioH%:"!'+/57;="..,0IsArwrxrc|rB|r@|dk(rtj|}|jjt ||S|r|jj|St d)NrMr-zEget_node requires one of the following: 1. node name 2. host and port)rOrPrrrr)rs rSrzNodesManager.get_nodesk D{"++D1##'' 4d(KL L ##'' 2 2# rboldnew remove_oldcP|rUt|jD]9}||vstj|j |j ;|j D]<\}}||vr.|||urtj||j |||<>yr)rrrrrr^rO)rrxryrzrrs rS set_nodeszNodesManager.set_nodess SXXZ( Fs?))#''$-*B*B*DE F))+ JD$s{t9$%%c$i&:&:&<=CI  rbc6|j}|j|j|j}|r|jt k7rdt |_nXt |j|jt fi|j}|j|j|j|i||j|jvr|j|jd}t|_|j|jj||j|jj|||j|jd<|j |k(r)||_d|_y|g|j|j<d|_y)Nr-r)r0rrwrxrKrr8rnr|rrrslot_idrrremover)rr%redirected_node old_primarys rS_update_moved_slotsz NodesManager._update_moved_slotss\  ! !--QVV!&&-A **g5.5+*+/+A+AO NN4++o.B.BO-T U d..qyy9 9**1995a8K'.K #   QYY ' . .{ ;   QYY ' . . ?-rKcz|jjDcgc]}|j|k(r|c}Scc}wr)rrrK)rrKrs rSrz%NodesManager.get_nodes_by_server_typesA((//1 ;.    s8c K|jji}i}g}d}d}|jjD]} |j dd{j ds t d|j dd{}d}t|d k(r8|d dd s-t|jd k(r|j|d dd <|D]} tdt| D]!} | | D cgc] } t!| c} | | <#| d} | d }|dk(r |j}t#| d }|j t%||}|st'||t(fi|j*}|||j<tt#| d t#| d d zD]-} | |vrg|| <|| j-|tdt| Dcgc]}| | }}|D]h}|d }|d }|j t%||}|st'||t.fi|j*}|| j-||||j<j|| d }|j|jk7s|j-|jd|jd| t|dkDst ddj1|d}tt2D] } | |vsd}n|sn|s t d|s+|j4rt dt|dt2d||_|j9|j:|d|j9|j|j:d|j=t(d |_d|_ y7\7,#ttf$rYt$r4}|j} d| vsd| vrYd}~t d |d | d}~wt$r0}|j} t d |jd | d}~wwxYwcc} wcc}ww)NFINFOcluster_enabledz(Cluster mode is not enabled on this noderTrZr\z7ERROR sending "cluster slots" command to redis server: z . error: z6ERROR sending "cluster slots" command to redis server rrrr;z vs z on slot: r+z6startup_nodes could not agree on a valid slots cache: z, zORedis Cluster cannot be connected. Please provide at least one reachable node. z9All slots are not covered after query all startup_nodes. z of z covered...)rz)!ruresetryrr'rr,r(r/r-__str__rbrrrwrr6rrr8rrnrrjoinr!rzrr|rrrr0)rtmp_nodes_cache tmp_slots disagreementsstartup_nodes_reachable fully_covered startup_node cluster_slotsr%rrival primary_noderwrxr(j replica_nodes replica_nodetarget_replica_nodetmp_slots rSrzNodesManager.initializes %%'4646  "'  ..557j L *::6BBGG%0B'3&B&B?&S S *.':M"a'%a(+A.**+q0)5):): a #A&%4 "q#d),EA<@GDS|C0DDGE#Aw #A2:',,D<?+-11-d2KL ""-dG#/3/E/E#K5@ 0 01s47|Sa\A-=>#"A )') ! !! ++K8:?3t9:M(NQa(N (N,94L#/?D#/?D2A2E2E -dD 93/$76A$($7";?;Q;Q7" 3&aL//0CD!4, 3 8 84&$-Q<?#==K,<,<<)00#+==/k6F6F5GzRSQT U #=1A5&;'448IIm4L3M%O'"!"A#"#4 "n!M34 I%$)M Uj X'''  !;!;(Ky>"$'?&@A % t''TJ t))4+;+;M!99'B1E $EC !T#\2  ))+ G+|w/F/##/. 'D ))++*//0 'D .E&)OsAQN<N62N< N9N<A+Q?Q CQ) Q 5BQ;Q9Q>QB/Q6N<9N<<Q QQP.Q4P Q+P<<Q QattrcKd|_tjdt||j Dd{y7w)Nc3bK|]'}tj|j)ywrr]rrs rSrz%NodesManager.close..s*%%doo&78r_)rrrgetattrr)rrs rSrzNodesManager.closesA nn#D$/668   sK|jd{S7wrrrs rSrzClusterPipeline.__aenter__rrcKg|_ywrrFrs rSrzClusterPipeline.__aexit__s s c>|jjSrrrs rSrzClusterPipeline.__await__rrbcg|_|Srrrs rS __enter__zClusterPipeline.__enter__s  rbcg|_yrrrs rS__exit__zClusterPipeline.__exit__s  rbc,t|jSr)rDrFrs rS__bool__zClusterPipeline.__bool__sD''((rbc,t|jSr)rrFrs rS__len__zClusterPipeline.__len__s4&&''rbrrLc||jjtt|jg|i||S)ad Append a raw command to the pipeline. :param args: | Raw command args :param kwargs: - target_nodes: :attr:`NODE_FLAGS` or :class:`~.ClusterNode` or List[:class:`~.ClusterNode`] or Dict[Any, :class:`~.ClusterNode`] - Rest of the kwargs are passed to the Redis connection )rFrPipelineCommandr)rrrLs rSr'zClusterPipeline.execute_commands< "" C 3 34 Ft Fv F  rbraise_on_errorallow_redirectionscrK|jsgS t|jjD]t}|jjr"|jj d{ |j |j|j||d{cg|_S7B7#t$rq}t||jjvrD|}|jjd{7tjdd{7n|Yd}~d}~wwxYw#g|_wxYww)a  Execute the pipeline. It will retry the commands as specified by :attr:`cluster_error_retry_attempts` & then raise an exception. :param raise_on_error: | Raise the first error if there are any errors :param allow_redirections: | Whether to retry each failed command individually in case of redirection errors :raises RedisClusterException: if target_nodes is not provided & the command can't be mapped to a slot N)rrr,)rFrrrkrir_executerrrrrrr/)rrrr#r%r&s rSexecutezClusterPipeline.execute s$""I %4<<DDE <<++,,11333 !% ++'5+= "/"&#%D 1 ,O)4 % Aw$.."C"CC$% "ll00222%mmD111 2  #%D sD7AD+'B*(D+-,B.B,B.D+D7'D+,B.. D(7AD#7C:8D#DD#D+#D((D++ D44D7rdstackrc>K|Dcgc]+}|jrt|jts*|-}}i}|D]}|jj dd}|r#|j |s|j |} n?|j|jd|id{} | std|jdt| dkDrtd|j| d} | j|vr| || j<g| _ | jj|tjd|j!Dd{} t#| r|ra|D]\}t|jt$t&t(fs) |j*|ji|jd{|_^|r|D]}|j} t| ts d j-t/t0|j}d |j2dzd |d | j}|f| jddz| _| |Dcgc]}|jc}Scc}w777#t$r} | |_Yd} ~ &d} ~ wwxYwcc}ww) Nr rrrrzToo many targets for command rc3bK|]'}tj|j)ywr)rrrsrs rSrz+ClusterPipeline._execute..]s$ Xg##D$9$9$;< Xr_rz Command #  (z) of pipeline caused error: )rrr rbrLrr rrrr,rrrFrrrranyr0r+r#r'rmapr5position)rrrrrrtodorr"r rerrorsr%rrrmsgs rSrzClusterPipeline._execute;s!  jY6WC   ,C ZZ^^NDANf&:&:>&J%99.I % $  %',,s ,,m    * )+)*CJJ+-sJ+I-I-A)J I2!B5JI5;J)I:=I8> I:%J-A*JJ* J5J8I:: JJ JJJrrc|jj|jD]}|j|g||Sr)r_partition_keys_by_slotrr')rrr slot_keyss rS_split_command_across_slotsz+ClusterPipeline._split_command_across_slotszsG==dCJJL 6I D  59 5 6 rbmappingc,|jj}i}|jD]@}t|j |d}|j |gj |B|jD]}|jdg||S)NrMSET) rrorOr"r setdefaultextendrr')rrro slots_pairspairrpairss rSmset_nonatomiczClusterPipeline.mset_nonatomics,,&& MMO :DGNN4734D  " "4 , 3 3D 9 :!'') 1E D  0% 0 1 rb)rMr8r>)TT)r]r^r_rArCrdrrrrrrrrrrDrrrr r3r2r'rrrr rrr1rrarbrSr8r8s@"H.I:|::  '!-9S$0A%AB-!)$)((4+,8; (GK.%".%?C.% c.%h $#' =-=-%&=- =- ! =- c =-~#'  w 23   rbr8rr#rc0eZdZdedededdfdZdefdZy)rrrrLrMNc<||_||_||_d|_yr)rrLrrr)rrrrLs rSrzPipelineCommand.__init__s    -1 rbcVd|jd|jd|jdS)N[z] r))rrrLrs rSrUzPipelineCommand.__repr__s)4==/DII;b Q??rb)r]r^r_rrrr rUrarbrSrrs122S2C2D2 @#@rbr)RrrQrrOrtypingrrrrrrr r r r redis.asyncio.clientr redis.asyncio.connectionrrrrredis.asyncio.parserr redis.clientrrr redis.clusterrrrrrrrrrredis.commandsrr redis.crcr!r"redis.exceptionsr#r$r%r&r'r(r)r*r+r,r-r.r/r0 redis.typingr1r2r3 redis.utilsr4r5r6r r7rPrTrVrdr8rr8rreplacelowersetattrrrarbrSrsa    3RR/DD   D8 32::C](;T#}BT=U .MSMT#s(^M M E %="68QE %PddNY Y x_m%9;T_D)GGooc3'--/G"" OW&