Ϫfc\dZddlmZddlmZmZmZddlmZddl m Z ddl m Z ddl mZmZdZGd d eZGd d eZGd deZGddZGddee ZgdZy)ap Memcache client protocol. Memcached is a caching server, storing data in the form of pairs key/value, and memcache is the protocol to talk with it. To connect to a server, create a factory for L{MemCacheProtocol}:: from twisted.internet import reactor, protocol from twisted.protocols.memcache import MemCacheProtocol, DEFAULT_PORT d = protocol.ClientCreator(reactor, MemCacheProtocol ).connectTCP("localhost", DEFAULT_PORT) def doSomething(proto): # Here you call the memcache operations return proto.set("mykey", "a lot of data") d.addCallback(doSomething) reactor.run() All the operations of the memcache protocol are present, but L{MemCacheProtocol.set} and L{MemCacheProtocol.get} are the more important. See U{http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt} for more information about the protocol. )deque)Deferred TimeoutErrorfail) LineReceiver) TimeoutMixin)log) nativeString networkStringi+ceZdZdZy) NoSuchCommandzA Exception raised when a non existent command is called. N__name__ __module__ __qualname____doc__?@ %%'rc`d|_|j|tj||y)z9 Cause any outstanding commands to fail. TN) _disconnectedr<rconnectionLost)r"r:s rrDzMemCacheProtocol.connectionLosts*" V$##D&1rc~|js|j|jtj||y)zA Override sendLine to add a timeout to response. N)r2 setTimeoutr6rsendLine)r"lines rrGzMemCacheProtocol.sendLines-}} OOD22 3dD)rcN|j|jj||xjt |z c_|j|j dzk\rdj |j}|d|j }||j dzd}|}d|_d|_d|_|jd}|jr9|j|j\}}|||f|j|j<n||_ |j|yy)z) Collect data for a get. rNr) resetTimeoutr4appendr5lenr3joinr2multiplevalues currentKeyr) setLineMode)r"databufremvalr;flagscass rrawDataReceivedz MemCacheProtocol.rawDataReceiveds  t$ c$i'   !2!2Q!6 688DOO,D***+Ct((1,./CC $D "DO!%D --"C|| ZZ7 s.3S#-> 3>>*   S ! 7rcV|jjjdy)z? Manage a success response to a set operation. TNr2r9r*r@s r cmd_STOREDzMemCacheProtocol.cmd_STORED ''-rcV|jjjdy)z Manage a specific 'not stored' response to a set operation: this is not an error, but some condition wasn't met. FNr[r@s rcmd_NOT_STOREDzMemCacheProtocol.cmd_NOT_STOREDs ''.rc |jj}|jdk(ry|jrE|jj Dcic]\}}||ddd}}}|j |y|j |j|jfy|jdk(r[|jr|j |jy|j |j|j|jfy|jdk(r|j |jytdjt|jcc}}w)zB This the end token to a get or a stat operation. getNrJgetsstatsz%Unexpected END response to {} command) r2r9rrOrPr r*rWr)rX RuntimeErrorformatr )r"r;keyrVrPs rcmd_ENDzMemCacheProtocol.cmd_ENDs mm##% ;;& ||8; 8H8H8JKHC#s3Q3x-KK F# SYY 23 [[G #|| CJJ' SYY;< [[H $ KK #7>> - LsE%cV|jjjdy)z= Manage error response for incr/decr/delete. FNr[r@s r cmd_NOT_FOUNDzMemCacheProtocol.cmd_NOT_FOUND ''.rc|jd}|jdk(r|j\}}}d}n|j\}}}}t||_g|_d|_|jr;||jvr td||_ t||g|j|<n1|j|k7r tdt||_ ||_|jy)z: Prepare the reading a value after a get. rrarzUnexpected commands answer.N)r2rsplitintr3r4r5rOkeysrdrQrPrfrWrX setRawMode)r"rHr;rfrWlengthrXs r cmd_VALUEzMemCacheProtocol.cmd_VALUEsmmA ;;& !% CC&*jjl #CK <<#((""#@AA CN"5z3/CJJsOww#~"#@AAE CICG rcj|jd}|jdd\}}||j|<y)z- Reception of one stat line. r N)r2rlrP)r"rHr;rfrVs rcmd_STATzMemCacheProtocol.cmd_STAT s3mmA::dA&S 3rcV|jjj|y)z% Read version token. Nr[)r" versionDatas r cmd_VERSIONzMemCacheProtocol.cmd_VERSIONs '' 4rctjd|jj}|j t y)z7 A non-existent command has been sent. zNon-existent command sent.N)r errr2r9rr )r"r;s r cmd_ERRORzMemCacheProtocol.cmd_ERRORs1 ,-mm##% !rct|}tjd|z|jj }|j t |y)z0 An invalid input as been sent. zInvalid input: N)reprr rzr2r9rrr"errTextr;s rcmd_CLIENT_ERRORz!MemCacheProtocol.cmd_CLIENT_ERRORsBw- !G+,mm##% W%&rct|}tjd|z|jj }|j t |y)z4 An error has happened server-side. zServer error: N)r}r rzr2r9rrr~s rcmd_SERVER_ERRORz!MemCacheProtocol.cmd_SERVER_ERROR(sBw-  7*+mm##% W%&rcV|jjjdy)z> A delete command has completed successfully. TNr[r@s r cmd_DELETEDzMemCacheProtocol.cmd_DELETED1r]rcV|jjjdy)z6 The last command has been completed. TNr[r@s rcmd_OKzMemCacheProtocol.cmd_OK7r]rcV|jjjdy)z5 A C{checkAndSet} update has failed. FNr[r@s r cmd_EXISTSzMemCacheProtocol.cmd_EXISTS=rjrc|j|jddd}t|dt|zd}|+|jdddd}|r ||dns|nk|j dd}t|dt|zd}||n6|j j }t|}|j||j s|jdyy)z8 Receive line commands from the server. rsrtrcmd_N_) rKrlgetattrr replacer2r9rmr*rF)r"rHtokenr;argsrVs r lineReceivedzMemCacheProtocol.lineReceivedCs  4#A&dF\%%88$? ?::dA&qr*DDG <<d+D$d); ;TBCmm++-$i C }} OOD !rc(|jd||S)a Increment the value of C{key} by given value (default to 1). C{key} must be consistent with an int. Return the new value. @param key: the key to modify. @type key: L{bytes} @param val: the value to increment. @type val: L{int} @return: a deferred with will be called back with the new value associated with the key (after the increment). @rtype: L{Deferred} sincr _incrdecrr"rfrVs r incrementzMemCacheProtocol.increment`s~~gsC00rc(|jd||S)a Decrement the value of C{key} by given value (default to 1). C{key} must be consistent with an int. Return the new value, coerced to 0 if negative. @param key: the key to modify. @type key: L{bytes} @param val: the value to decrement. @type val: L{int} @return: a deferred with will be called back with the new value associated with the key (after the decrement). @rtype: L{Deferred} sdecrrrs r decrementzMemCacheProtocol.decrementqs ~~gsC00rc|jrttdSt|ts!tt dt |dSt||jkDrtt dSdj||dt|fzg}|j|t||}|jj||jS)z1 Internal wrapper for incr/decr. not connectedInvalid type for key: , expecting bytes Key too longrss%drf)rCrrd isinstancebytesrtyperMMAX_KEY_LENGTHrNrmrGrr2rLr)r"r;rfrVfullcmdcmdObjs rrzMemCacheProtocol._incrdecrs    _56 6#u%4T#YK?PQR  s8d)) ) N34 4))S#uC{':;< g#& V$rc.|jd||||dS)a Replace the given C{key}. It must already exist in the server. @param key: the key to replace. @type key: L{bytes} @param val: the new value associated with the key. @type val: L{bytes} @param flags: the flags to store with the key. @type flags: L{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: L{int} @return: a deferred that will fire with C{True} if the operation has succeeded, and C{False} with the key didn't previously exist. @rtype: L{Deferred} sreplacer_setr"rfrVrW expireTimes rrzMemCacheProtocol.replaces*yyS#uj#FFrc.|jd||||dS)a Add the given C{key}. It must not exist in the server. @param key: the key to add. @type key: L{bytes} @param val: the value associated with the key. @type val: L{bytes} @param flags: the flags to store with the key. @type flags: L{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: L{int} @return: a deferred that will fire with C{True} if the operation has succeeded, and C{False} with the key already exists. @rtype: L{Deferred} saddrrrs raddzMemCacheProtocol.add*yyc5*cBBrc.|jd||||dS)a9 Set the given C{key}. @param key: the key to set. @type key: L{bytes} @param val: the value associated with the key. @type val: L{bytes} @param flags: the flags to store with the key. @type flags: L{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: L{int} @return: a deferred that will fire with C{True} if the operation has succeeded. @rtype: L{Deferred} ssetrrrs rsetzMemCacheProtocol.setrrc.|jd|||||S)am Change the content of C{key} only if the C{cas} value matches the current one associated with the key. Use this to store a value which hasn't been modified since last time you fetched it. @param key: The key to set. @type key: L{bytes} @param val: The value associated with the key. @type val: L{bytes} @param cas: Unique 64-bit value returned by previous call of C{get}. @type cas: L{bytes} @param flags: The flags to store with the key. @type flags: L{int} @param expireTime: If different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: L{int} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} scasr)r"rfrVrXrWrs r checkAndSetzMemCacheProtocol.checkAndSets4yyc5*cBBrc ~|jrttdSt|ts!tt dt |dSt||jkDrtt dSt|ts!tt dt |dS|rd|z}t|}dj||td|||fzg|z}|j||j|t||||} |jj| | jS) z6 Internal wrapper for setting values. rrrrzInvalid type for value: rsz%d %d %d)rfrWrp)rCrrdrrrrrMrrNr rGrr2rLr) r"r;rfrVrWrrXrprrs rrzMemCacheProtocol._sets2    _56 6#u%4T#YK?PQR  s8d)) ) N34 4#u%6tCykARST  *CS IIc=uj&6Q)QRS    g c#U6B V$rc.|jd||dddS)a Append given data to the value of an existing key. @param key: The key to modify. @type key: L{bytes} @param val: The value to append to the current value associated with the key. @type val: L{bytes} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} sappendrrrrs rrLzMemCacheProtocol.appends yyCaC88rc.|jd||dddS)a Prepend given data to the value of an existing key. @param key: The key to modify. @type key: L{bytes} @param val: The value to prepend to the current value associated with the key. @type val: L{bytes} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} sprependrrrrs rprependzMemCacheProtocol.prepend's yyS#q!S99rc*|j|g|dS)a Get the given C{key}. It doesn't support multiple keys. If C{withIdentifier} is set to C{True}, the command issued is a C{gets}, that will return the current identifier associated with the value. This identifier has to be used when issuing C{checkAndSet} update later, using the corresponding method. @param key: The key to retrieve. @type key: L{bytes} @param withIdentifier: If set to C{True}, retrieve the current identifier along with the value and the flags. @type withIdentifier: L{bool} @return: A deferred that will fire with the tuple (flags, value) if C{withIdentifier} is C{False}, or (flags, cas identifier, value) if C{True}. If the server indicates there is no value associated with C{key}, the returned value will be L{None} and the returned flags will be C{0}. @rtype: L{Deferred} F_get)r"rfwithIdentifiers rgetzMemCacheProtocol.get9s,yy#66rc(|j||dS)a Get the given list of C{keys}. If C{withIdentifier} is set to C{True}, the command issued is a C{gets}, that will return the identifiers associated with each values. This identifier has to be used when issuing C{checkAndSet} update later, using the corresponding method. @param keys: The keys to retrieve. @type keys: L{list} of L{bytes} @param withIdentifier: If set to C{True}, retrieve the identifiers along with the values and the flags. @type withIdentifier: L{bool} @return: A deferred that will fire with a dictionary with the elements of C{keys} as keys and the tuples (flags, value) as values if C{withIdentifier} is C{False}, or (flags, cas identifier, value) if C{True}. If the server indicates there is no value associated with C{key}, the returned values will be L{None} and the returned flags will be C{0}. @rtype: L{Deferred} @since: 9.0 Tr)r"rnrs r getMultiplezMemCacheProtocol.getMultipleQs0yy~t44rc Ft|}|jrttdS|D]c}t |t s#tt dt|dcSt||jkDsOtt dcS|rd}nd}dj|g|z}|j||r |Dcic]}|d}}t|||d }nt||d d d d d}|jj||jScc}w)z> Helper method for C{get} and C{getMultiple}. rrrrrbrars)rrNT)rnrPrOrNrF)rfr)rWrXrO)listrCrrdrrrrrMrrNrGrr2rLr) r"rnrrOrfr;rrPrs rrzMemCacheProtocol._getks!Dz    _56 6 9Cc5)"8c CT UV3x$---K788  9 CC))SEDL) g 59:cc>):F:StFTJFaA3F V$;s DNc|rd|z}nd}|jrttdS|j|t di}|j j ||jS)a Get some stats from the server. It will be available as a dict. @param arg: An optional additional string which will be sent along with the I{stats} command. The interpretation of this value by the server is left undefined by the memcache protocol specification. @type arg: L{None} or L{bytes} @return: a deferred that will fire with a L{dict} of the available statistics. @rtype: L{Deferred} sstats rcr)rPrCrrdrGrr2rLr)r"argr;rs rstatszMemCacheProtocol.statssd c/CC    _56 6 c"- V$rc|jrttdS|jdt d}|j j ||jS)z Get the version of the server. @return: a deferred that will fire with the string value of the version. @rtype: L{Deferred} rsversionrr"rs rversionzMemCacheProtocol.versionsQ    _56 6 j!$ V$rc4|jrttdSt|ts!tt dt |dS|jd|ztd|}|jj||jS)a Delete an existing C{key}. @param key: the key to delete. @type key: L{bytes} @return: a deferred that will be called back with C{True} if the key was successfully deleted, or C{False} if not. @rtype: L{Deferred} rrrsdelete sdeleter) rCrrdrrrrrGrr2rLr)r"rfrs rdeletezMemCacheProtocol.deletes    _56 6#u%4T#YK?PQR  j3&', V$rc|jrttdS|jdt d}|j j ||jS)z Flush all cached values. @return: a deferred that will be called back with C{True} when the operation has succeeded. @rtype: L{Deferred} rs flush_allrrs rflushAllzMemCacheProtocol.flushAllsQ    _56 6 l#& V$r)<)rt)rr)F)N)+rrrrrrCr&r<rArDrGrYr\r_rgrirqrurxr{rrrrrrrrrrrrrrrLrrrrrrrrrrrr/r/cs2NM 8(2*".. /2/ 25 "''. . / ":1"1$ $G.C.C.C8 >9$:$7054 < 2   ,  rr/)r/ DEFAULT_PORTr rrN)r collectionsrtwisted.internet.deferrrrtwisted.protocols.basicrtwisted.protocols.policiesrtwisted.pythonr twisted.python.compatr r r Exceptionr rrrr/__all__rrrrsm 0??03= I ) ) &&&&Rq  |\q  h r