ó #[Qc@sòdZddlmZddlmZddlmZddlmZm Z m Z ddl m Z dZ defd „ƒYZd efd „ƒYZd efd „ƒYZdefd„ƒYZdeefd„ƒYZdddd d gZdS(sp 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. iÿÿÿÿ(tdeque(t LineReceiver(t TimeoutMixin(tDeferredtfailt TimeoutError(tlogiË+t NoSuchCommandcBseZdZRS(sA Exception raised when a non existent command is called. (t__name__t __module__t__doc__(((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR)st ClientErrorcBseZdZRS(s1 Error caused by an invalid client call. (RR R (((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR 0st ServerErrorcBseZdZRS(s* Problem happening on the server. (RR R (((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR 7stCommandcBs)eZdZd„Zd„Zd„ZRS(s6 Wrap a client action into an object, that holds the values used in the protocol. @ivar _deferred: the L{Deferred} object that will be fired when the result arrives. @type _deferred: L{Deferred} @ivar command: name of the command sent to the server. @type command: C{str} cKsF||_tƒ|_x*|jƒD]\}}t|||ƒq"WdS(sÝ Create a command. @param command: the name of the command. @type command: C{str} @param kwargs: this values will be stored as attributes of the object for future use N(tcommandRt _deferredtitemstsetattr(tselfRtkwargstktv((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt__init__Ks  cCs|jj|ƒdS(sB Shortcut method to fire the underlying deferred. N(Rtcallback(Rtvalue((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytsuccess[scCs|jj|ƒdS(s5 Make the underlying deferred fails. N(Rterrback(Rterror((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRbs(RR R RRR(((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR >s   tMemCacheProtocolcBs‘eZdZdZeZdd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zdd„Zdd„Zd„Zddd„Zddd„Zddd„Zddd„Z d „Z!d!„Z"d"„Z#ed#„Z$ed$„Z%d%„Z&d*d&„Z(d'„Z)d(„Z*d)„Z+RS(+s1 MemCache protocol: connect to a memcached server to store/retrieve values. @ivar persistentTimeOut: the timeout period used to wait for a response. @type persistentTimeOut: C{int} @ivar _current: current list of requests waiting for an answer from the server. @type _current: C{deque} of L{Command} @ivar _lenExpected: amount of data expected in raw mode, when reading for a value. @type _lenExpected: C{int} @ivar _getBuffer: current buffer of data, used to store temporary data when reading in raw mode. @type _getBuffer: C{list} @ivar _bufferLength: the total amount of bytes in C{_getBuffer}. @type _bufferLength: C{int} @ivar _disconnected: indicate if the connectionLost has been called or not. @type _disconnected: C{bool} iúi<cCs;tƒ|_d|_d|_d|_||_|_dS(sÓ Create the protocol. @param timeOut: the timeout to wait before detecting that the connection is dead and close it. It's expressed in seconds. @type timeOut: C{int} N(Rt_currenttNonet _lenExpectedt _getBuffert _bufferLengthtpersistentTimeOutttimeOut(RR#((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR†s     cCs0x)|jr+|jjƒ}|j|ƒqWdS(sW Cancel all the outstanding commands, making them fail with C{reason}. N(RtpopleftR(Rtreasontcmd((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt_cancelCommands•s cCs$|jtdƒƒ|jjƒdS(s: Close the connection in case of timeout. sConnection timeoutN(R'Rt transporttloseConnection(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyttimeoutConnectionžscCs*t|_|j|ƒtj||ƒdS(s9 Cause any outstanding commands to fail. N(tTruet _disconnectedR'RtconnectionLost(RR%((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR-¦s  cCs0|js|j|jƒntj||ƒdS(sA Override sendLine to add a timeout to response. N(Rt setTimeoutR"RtsendLine(Rtline((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR/¯s cCsû|jƒ|jj|ƒ|jt|ƒ7_|j|jdkr÷dj|jƒ}||j }||jd}|}d|_d|_d|_|jd}|j rÞ|j |j \}}|||f|j |j /usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytrawDataReceived¸s"        cCs|jjƒjtƒdS(s? Manage a success response to a set operation. N(RR$RR+(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_STOREDÐscCs|jjƒjtƒdS(sŠ Manage a specific 'not stored' response to a set operation: this is not an error, but some condition wasn't met. N(RR$RtFalse(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_NOT_STORED×scCs|jjƒ}|jdkr”|jrxtg|jjƒD]%\}}||ddd…f^q:ƒ}|j|ƒq|j|j|j fƒno|jdkrá|jr¿|j|jƒq|j|j|j |j fƒn"|jdkr|j|jƒndS(sB This the end token to a get or a stat operation. tgetNitgetststats( RR$RR6tdictR7t iteritemsRR>RR?(RR&tkeyR=R7((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_ENDßs ; "cCs|jjƒjtƒdS(s= Manage error response for incr/decr/delete. N(RR$RRB(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_NOT_FOUNDôscCs|jd}|jdkr:|jƒ\}}}d}n|jƒ\}}}}t|ƒ|_g|_d|_|jr¿||jkršt dƒ‚n||_ t|ƒ|g|j |R?t setRawMode(RR0R&RIR>tlengthR?((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_VALUEûs$       cCs6|jd}|jddƒ\}}||j|/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_STATs cCs|jjƒj|ƒdS(s% Read version token. N(RR$R(Rt versionData((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_VERSIONscCs0tjdƒ|jjƒ}|jtƒƒdS(s8 An non-existent command has been sent. sNon-existent command sent.N(RterrRR$RR(RR&((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_ERROR%s cCs:tjd|fƒ|jjƒ}|jt|ƒƒdS(s0 An invalid input as been sent. sInvalid input: %sN(RRWRR$RR (RterrTextR&((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_CLIENT_ERROR.scCs:tjd|fƒ|jjƒ}|jt|ƒƒdS(s4 An error has happened server-side. sServer error: %sN(RRWRR$RR (RRYR&((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_SERVER_ERROR7scCs|jjƒjtƒdS(s> A delete command has completed successfully. N(RR$RR+(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_DELETED@scCs|jjƒjtƒdS(s6 The last command has been completed. N(RR$RR+(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytcmd_OKGscCs|jjƒjtƒdS(s5 A C{checkAndSet} update has failed. N(RR$RRB(R((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt cmd_EXISTSNscCs|jƒ|jddƒd}t|d|fdƒ}|dk r||jddƒd}|rr||dƒqå|ƒni|jddƒ}t|d|fdƒ}|dk r½|ƒn(|jjƒ}t|ƒ}|j|ƒ|jsþ|j dƒndS(s8 Receive line commands from the server. RSiiscmd_%st_N( R2RLtgetattrRtreplaceRR$RMRR.(RR0ttokenR&targsR=((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt lineReceivedUs"        icCs|jd||ƒS(s¼ 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: C{str} @param val: the value to increment. @type val: C{int} @return: a deferred with will be called back with the new value associated with the key (after the increment). @rtype: L{Deferred} tincr(t _incrdecr(RRIR=((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt incrementsscCs|jd||ƒS(sÞ 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: C{str} @param val: the value to decrement. @type val: C{int} @return: a deferred with will be called back with the new value associated with the key (after the decrement). @rtype: L{Deferred} tdecr(Rf(RRIR=((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt decrement…scCs¹|jrttdƒƒSt|tƒsEttdt|ƒfƒƒSt|ƒ|jkrjttdƒƒSd||t |ƒf}|j |ƒt |d|ƒ}|j j |ƒ|jS(s1 Internal wrapper for incr/decr. s not connecteds,Invalid type for key: %s, expecting a strings Key too longs%s %s %dRI(R,RROt isinstancetstrR ttypeR4tMAX_KEY_LENGTHRMR/R RR3R(RR&RIR=tfullcmdtcmdObj((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRf˜s  icCs|jd||||dƒS(s™ Replace the given C{key}. It must already exist in the server. @param key: the key to replace. @type key: C{str} @param val: the new value associated with the key. @type val: C{str} @param flags: the flags to store with the key. @type flags: C{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: C{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} RaR1(t_set(RRIR=R>t expireTime((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRaªscCs|jd||||dƒS(s€ Add the given C{key}. It must not exist in the server. @param key: the key to add. @type key: C{str} @param val: the value associated with the key. @type val: C{str} @param flags: the flags to store with the key. @type flags: C{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: C{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} taddR1(Rp(RRIR=R>Rq((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRrÂscCs|jd||||dƒS(s5 Set the given C{key}. @param key: the key to set. @type key: C{str} @param val: the value associated with the key. @type val: C{str} @param flags: the flags to store with the key. @type flags: C{int} @param expireTime: if different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: C{int} @return: a deferred that will fire with C{True} if the operation has succeeded. @rtype: L{Deferred} tsetR1(Rp(RRIR=R>Rq((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRsÚscCs|jd|||||ƒS(sg 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: C{str} @param val: The value associated with the key. @type val: C{str} @param cas: Unique 64-bit value returned by previous call of C{get}. @type cas: C{str} @param flags: The flags to store with the key. @type flags: C{int} @param expireTime: If different from 0, the relative time in seconds when the key will be deleted from the store. @type expireTime: C{int} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} R?(Rp(RRIR=R?R>Rq((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt checkAndSetòsc Cs |jrttdƒƒSt|tƒsEttdt|ƒfƒƒSt|ƒ|jkrjttdƒƒSt|tƒs–ttdt|ƒfƒƒS|r©d|}nt|ƒ}d||||||f}|j |ƒ|j |ƒt |d|d|d |ƒ} |j j | ƒ| j S( s6 Internal wrapper for setting values. s not connecteds,Invalid type for key: %s, expecting a strings Key too longs.Invalid type for value: %s, expecting a stringRSs%s %s %d %d %d%sRIR>RQ(R,RRORjRkR RlR4RmR/R RR3R( RR&RIR=R>RqR?RQRnRo((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRps*     cCs|jd||dddƒS(s˜ Append given data to the value of an existing key. @param key: The key to modify. @type key: C{str} @param val: The value to append to the current value associated with the key. @type val: C{str} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} R3iR1(Rp(RRIR=((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR3*scCs|jd||dddƒS(sš Prepend given data to the value of an existing key. @param key: The key to modify. @type key: C{str} @param val: The value to prepend to the current value associated with the key. @type val: C{str} @return: A deferred that will fire with C{True} if the operation has succeeded, C{False} otherwise. @rtype: L{Deferred} tprependiR1(Rp(RRIR=((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRu=scCs|j|g|tƒS(s¼ 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: C{str} @param withIdentifier: If set to C{True}, retrieve the current identifier along with the value and the flags. @type withIdentifier: C{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 C{None} and the returned flags will be C{0}. @rtype: L{Deferred} (t_getRB(RRItwithIdentifier((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRDPscCs|j||tƒS(s 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: C{list} of C{str} @param withIdentifier: If set to C{True}, retrieve the identifiers along with the values and the flags. @type withIdentifier: C{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 C{None} and the returned flags will be C{0}. @rtype: L{Deferred} @since: 9.0 (RvR+(RRNRw((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyt getMultipleisc CsG|jrttdƒƒSx_|D]W}t|tƒsRttdt|ƒfƒƒSt|ƒ|jkr ttdƒƒSq W|rŠd}nd}d|dj |ƒf}|j |ƒ|rt g|D]}|df^qƃ}t |d |d |d tƒ}n.t |d |ddddddd d tƒ}|jj|ƒ|jS(s> Helper method for C{get} and C{getMultiple}. s not connecteds,Invalid type for key: %s, expecting a strings Key too longRERDs%s %sRSiR1RNR7R6RIRR>R?N(iR1N(R,RRORjRkR RlR4RmR5R/RGRR R+RBRR3R( RRNRwR6RIR&RnR7Ro((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRvƒs(    %!% cCsh|rd|}nd}|jr2ttdƒƒS|j|ƒtddiƒ}|jj|ƒ|jS(sï 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{NoneType} or L{str} @return: a deferred that will fire with a C{dict} of the available statistics. @rtype: L{Deferred} sstats RFs not connectedR7(R,RROR/R RR3R(RtargR&Ro((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRFžs   cCsI|jrttdƒƒS|jdƒtdƒ}|jj|ƒ|jS(sª Get the version of the server. @return: a deferred that will fire with the string value of the version. @rtype: L{Deferred} s not connectedtversion(R,RROR/R RR3R(RRo((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRz¸s    cCs|jrttdƒƒSt|tƒsEttdt|ƒfƒƒS|jd|ƒtdd|ƒ}|j j |ƒ|j S(s Delete an existing C{key}. @param key: the key to delete. @type key: C{str} @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} s not connecteds,Invalid type for key: %s, expecting a strings delete %stdeleteRI( R,RRORjRkR RlR/R RR3R(RRIRo((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyR{Ès cCsI|jrttdƒƒS|jdƒtdƒ}|jj|ƒ|jS(s· Flush all cached values. @return: a deferred that will be called back with C{True} when the operation has succeeded. @rtype: L{Deferred} s not connectedt flush_all(R,RROR/R RR3R(RRo((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pytflushAllÞs    N(,RR R RmRBR,RR'R*R-R/R@RARCRJRKRRRTRVRXRZR[R\R]R^RdRgRiRfRaRrRsRtRpR3RuRDRxRvRRFRzR{R}(((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyRjsP                         t DEFAULT_PORTN(R t collectionsRttwisted.protocols.basicRttwisted.protocols.policiesRttwisted.internet.deferRRRttwisted.pythonRR~t ExceptionRR R tobjectR Rt__all__(((s>/usr/lib/python2.7/dist-packages/twisted/protocols/memcache.pyts,ÿÿ‡