memcache 0.2.0.0 → 0.2.0.1
raw patch · 9 files changed
+60/−31 lines, 9 files
Files
- CHANGELOG.md +6/−0
- Database/Memcache/Client.hs +9/−8
- Database/Memcache/Cluster.hs +0/−3
- Database/Memcache/Socket.hs +4/−0
- Database/Memcache/Types.hs +16/−1
- README.md +1/−0
- TODO.md +12/−7
- memcache.cabal +7/−7
- test/Full.hs +5/−5
CHANGELOG.md view
@@ -1,3 +1,9 @@+# 0.2.0.1 - November 2nd, 2016++* Fix compatability with latest `data-default-class`+* Add new ReqRaw type for external clients to implement custom requests. Quite+ a hack right now, so behind a WARNING pragma.+ # 0.2.0.0 - May 27th, 2016 * Big design change to reduce code duplication (`Protocol` module gone).
Database/Memcache/Client.hs view
@@ -23,18 +23,18 @@ while unexpected errors are thrown as exceptions. Exceptions are either of type 'MemcacheError' or an 'IO' exception thrown by the network. -We support the following logic for handling failure in operatins:+We support the following logic for handling failure in operations: * __Timeouts__: we timeout any operation that takes too long and consider it failed. * __Retry__: on operation failure (timeout, network error) we close the- connection and rety the operation, doing this up to a configurable- maximum.+ connection and retry the operation, doing this up to a+ configurable maximum. * __Failover__: when an operation against a server in a cluster fails all retries, we mark that server as dead and use the remaining servers in the cluster to handle all operations. After a- configurable period of time as passed, we consider the server+ configurable period of time has passed, we consider the server alive again and try to use it. This can lead to consistency issues (stale data), but is usually fine for caching purposes and is the common approach in Memcached clients.@@ -43,7 +43,7 @@ also have the following concepts exposed by Memcached: [@version@] Each value has a 'Version' associated with it. This is simply a- numeric, monontonically increasing value. The version field+ numeric, monotonically increasing value. The version field allows for a primitive version of 'cas' to be implemented. [@expiration@] Each value pair has an 'Expiration' associated with it. Once a@@ -54,8 +54,9 @@ considered expired. For example, an expiration of @3600@ expires the value in 1 hour. When the value of the expiration is greater than 30 days however (@2592000@), the expiration- field is instead interpretted as a UNIX timestamp (the number- of seconds since epoch).+ field is instead interpreted as a UNIX timestamp (the number+ of seconds since epoch). The timestamp specifies the date at+ which the value should expire. [@flags@] Each value can have a small amount of fixed metadata associated with it beyond the value itself, these are the 'Flags'.@@ -68,7 +69,7 @@ > > main = do > -- use default values: connects to localhost:11211-> mc <- M.newClient M.def M.def+> mc <- M.newClient [M.def] M.def > > -- store and then retrieve a key-value pair > M.set mc "key" "value" 0 0
Database/Memcache/Cluster.hs view
@@ -62,9 +62,6 @@ instance Default ServerSpec where def = ServerSpec "localhost" 11211 NoAuth -instance Default [ServerSpec] where- def = [def]- -- | Options specifies how a Memcached cluster should be configured. data Options = Options { -- | Number of times to retry an operation on failure. If consecutive
Database/Memcache/Socket.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} {-| Module : Database.Memcache.Socket@@ -216,6 +217,9 @@ ReqSASLList -> (0x20, Nothing, Nothing, mempty, 0) ReqSASLStart key v -> (0x21, Just key, Just v, mempty, 0) ReqSASLStep key v -> (0x22, Just key, Just v, mempty, 0)++ -- XXX: Should kill in future, ugly+ ReqRaw c k v (SERaw e n) -> (c, k, v, e, n) where szSESet (SESet f e) = fromWord32be f <> fromWord32be e
Database/Memcache/Types.hs view
@@ -22,12 +22,14 @@ Header(..), mEMCACHE_HEADER_SIZE, PktType(..), -- * Requests- Request(..), OpRequest(..), SESet(..), SEIncr(..), SETouch(..), emptyReq,+ Request(..), OpRequest(..), SESet(..), SEIncr(..), SETouch(..),+ SERaw(..), emptyReq, -- * Responses Response(..), OpResponse(..), emptyRes ) where +import Blaze.ByteString.Builder (Builder) import Data.ByteString (ByteString) import Data.Word @@ -109,11 +111,24 @@ | ReqSASLList | ReqSASLStart Key Value -- key: auth method, value: auth data | ReqSASLStep Key Value -- key: auth method, value: auth data (continued)++ -- | Raw request is custom requests, dangerous as no corresponding raw+ -- response...+ | ReqRaw Word8 (Maybe Key) (Maybe Value) SERaw deriving (Eq, Show) +{-# WARNING ReqRaw "This is dangerous; no future compatability guaranteed" #-}+ data SESet = SESet Flags Expiration deriving (Eq, Show) data SEIncr = SEIncr Initial Delta Expiration deriving (Eq, Show) data SETouch = SETouch Expiration deriving (Eq, Show)+data SERaw = SERaw Builder Int++instance Show SERaw where+ show _ = "SERaw _"++instance Eq SERaw where+ (==) _ _ = False data Request = Req { reqOp :: OpRequest,
README.md view
@@ -5,6 +5,7 @@ [](http://packdeps.haskellers.com/reverse/memcache) [][tl;dr Legal: BSD3] [](https://travis-ci.org/dterei/memcache-hs)+[](https://gitter.im/dterei/memcache-hs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [tl;dr Legal: BSD3]: https://tldrlegal.com/license/bsd-3-clause-license-(revised)
TODO.md view
@@ -1,19 +1,26 @@ ## ToDo Optional:+* Typeclass abstracting key and values+* MonadIO?+* Safe Haskell * Differentiate between two expiration modes? * Simpler interface?-* Is System.Timeout still slow? Switch to Warp/Snap timeout handler?-* Is NominalDiffTime slow? Switch to unix epoch time? * Configurable fail-over mode++Protocol: * Multi-get * Generic multi operation support-* Customizable server sharding -- mod & virtual servers +Performance:+* Is System.Timeout still slow? Switch to Warp/Snap timeout handler?+* Is NominalDiffTime slow? Switch to unix epoch time?+ Nice-to-have: * Smarter connection handling to minimize system calls (buffered)+* Customizable server sharding -- mod & virtual servers * Server weights-* Asynchronous support+* Asynchronous support? * Customizable -- timeout, max connection retries, hash algorithm * Max value validation * Optimizations -- http://code.google.com/p/spymemcached/wiki/Optimizations@@ -22,7 +29,5 @@ * Server error handling mode where we return misses and ignore sets Maybe:-* Typeclass for serialization-* Monad / Typeclass for memcache-* Automatic serialization / deserialization+* Automatic encoding and decoding of Haskell data types (using flags?)
memcache.cabal view
@@ -1,21 +1,21 @@ name: memcache-version: 0.2.0.0+version: 0.2.0.1 homepage: https://github.com/dterei/memcache-hs bug-reports: https://github.com/dterei/memcache-hs/issues synopsis: A memcached client library. description: - A client library for a memcached cluster. Memcached is an in-memory key-value+ A client library for a Memcached cluster. Memcached is an in-memory key-value store typically used as a distributed and shared cache. Clients connect to a- group of memcached servers and perform out-of-band caching for things like+ group of Memcached servers and perform out-of-band caching for things like SQL results, rendered pages, or third-party APIs. .- It supports the binary memcached protocol and SASL authentication. No support+ It supports the binary Memcached protocol and SASL authentication. No support for the ASCII protocol is provided. It supports connecting to a single, or a- cluster of memcached servers. When connecting to a cluser, consistent hashing+ cluster of Memcached servers. When connecting to a cluser, consistent hashing is used for routing requests to the appropriate server. Timeouts, retrying failed operations, and failover to a different server are all supported. .- Complete coverage of the memcached protocol is provided except for multi-get+ Complete coverage of the Memcached protocol is provided except for multi-get and other pipelined operations. . Basic usage is:@@ -42,7 +42,7 @@ Source-repository this type: git location: https://github.com/dterei/memcache-hs.git- tag: 0.1.0.1+ tag: 0.2.0.1 source-repository head type: git
test/Full.hs view
@@ -43,7 +43,7 @@ getTest :: IO () getTest = withMCServer False res $ do- c <- M.newClient M.def M.def+ c <- M.newClient [M.def] M.def void $ M.set c (BC.pack "key") (BC.pack "world") 0 0 Just (v', _, _) <- M.get c "key" when (v' /= "world") $ do@@ -56,7 +56,7 @@ deleteTest :: IO () deleteTest = withMCServer False res $ do- c <- M.newClient M.def M.def+ c <- M.newClient [M.def] M.def v1 <- M.set c "key" "world" 0 0 v2 <- M.set c "key" "world2" 0 0 when (v1 == v2) $ do@@ -74,7 +74,7 @@ retryTest :: IO () retryTest = withMCServer False res $ do- c <- M.newClient M.def M.def+ c <- M.newClient [M.def] M.def void $ M.set c (BC.pack "key") (BC.pack "world") 0 0 where res = [ CloseConnection@@ -83,7 +83,7 @@ timeoutTest :: IO () timeoutTest = withMCServer True res $ do- c <- M.newClient M.def M.def+ c <- M.newClient [M.def] M.def void $ M.set c (BC.pack "key") (BC.pack "world") 0 0 r <- try $ M.get c "key" case r of@@ -95,7 +95,7 @@ timeoutRetryTest :: IO () timeoutRetryTest = withMCServer False res $ do- c <- M.newClient M.def M.def+ c <- M.newClient [M.def] M.def void $ M.set c (BC.pack "key") (BC.pack "world") 0 0 where res = [ DelayMS 800 Noop