Copyright | (c) David Terei 2016 |
---|---|
License | BSD |
Maintainer | code@davidterei.com |
Stability | stable |
Portability | GHC |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Database.Memcache.Client
Description
A Memcached client. 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 SQL results, rendered pages, or third-party APIs.
A client can connect to a single Memcached server or a cluster of them. In the later case, consistent hashing is used to route requests to the appropriate server. The binary Memcached protocol is used and SASL authentication is supported.
Expected return values (like misses) are returned as part of the return type,
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 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 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 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.
Some of this behavior can be configured through the Options
data type. We
also have the following concepts exposed by Memcached:
version
- Each value has a
Version
associated with it. This is simply a numeric, monotonically increasing value. The version field allows for a primitive version ofcas
to be implemented. expiration
- Each value pair has an
Expiration
associated with it. Once a a value expires, it will no longer be returned from the cache until a new value for that key is set. Expirations come in two forms, the first form interprets the expiration value as the number of seconds in the future at which the value should be considered expired. For example, an expiration of3600
expires the value in 1 hour. When the value of the expiration is greater than 30 days however (2592000
), the expiration 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
.
Usage is roughly as follows:
module Main where import qualified Database.Memcache.Client as M main = do -- use default values: connects to localhost:11211 mc <- M.newClient [M.def] M.def -- store and then retrieve a key-value pair M.set mc "key" "value" 0 0 v' <- M.get mc "key" case v' of Nothing -> putStrLn "Miss!" Just (v, _, _) -> putStrLn $ "Hit: " + show v
Synopsis
- newClient :: [ServerSpec] -> Options -> IO Client
- type Client = Cluster
- data ServerSpec = ServerSpec {}
- data Options = Options {}
- data Authentication
- type Username = ByteString
- type Password = ByteString
- def :: Default a => a
- quit :: Cluster -> IO ()
- get :: Cluster -> Key -> IO (Maybe (Value, Flags, Version))
- gat :: Cluster -> Key -> Expiration -> IO (Maybe (Value, Flags, Version))
- touch :: Cluster -> Key -> Expiration -> IO (Maybe Version)
- set :: Cluster -> Key -> Value -> Flags -> Expiration -> IO Version
- cas :: Cluster -> Key -> Value -> Flags -> Expiration -> Version -> IO (Maybe Version)
- add :: Cluster -> Key -> Value -> Flags -> Expiration -> IO (Maybe Version)
- replace :: Cluster -> Key -> Value -> Flags -> Expiration -> Version -> IO (Maybe Version)
- increment :: Cluster -> Key -> Initial -> Delta -> Expiration -> Version -> IO (Maybe (Word64, Version))
- decrement :: Cluster -> Key -> Initial -> Delta -> Expiration -> Version -> IO (Maybe (Word64, Version))
- append :: Cluster -> Key -> Value -> Version -> IO (Maybe Version)
- prepend :: Cluster -> Key -> Value -> Version -> IO (Maybe Version)
- delete :: Cluster -> Key -> Version -> IO Bool
- flush :: Cluster -> Maybe Expiration -> IO ()
- type StatResults = [(ByteString, ByteString)]
- stats :: Cluster -> Maybe Key -> IO [(Server, Maybe StatResults)]
- version :: Cluster -> IO ByteString
- data MemcacheError
- data Status
- data ClientError
- data ProtocolError
- = UnknownPkt { }
- | UnknownOp { }
- | UnknownStatus { }
- | BadLength { }
- | WrongOp { }
- | UnexpectedEOF { }
Client creation
newClient :: [ServerSpec] -> Options -> IO Client Source #
Establish a new connection to a group of Memcached servers.
data ServerSpec Source #
ServerSpec specifies a server configuration for connection.
Constructors
ServerSpec | |
Fields
|
Instances
Show ServerSpec Source # | |
Defined in Database.Memcache.Cluster Methods showsPrec :: Int -> ServerSpec -> ShowS # show :: ServerSpec -> String # showList :: [ServerSpec] -> ShowS # | |
Default ServerSpec Source # | |
Defined in Database.Memcache.Cluster Methods def :: ServerSpec # | |
Eq ServerSpec Source # | |
Defined in Database.Memcache.Cluster |
Options specifies how a Memcached cluster should be configured.
Constructors
Options | |
Fields
|
data Authentication Source #
SASL Authentication information for a server.
Instances
Show Authentication Source # | |
Defined in Database.Memcache.Types Methods showsPrec :: Int -> Authentication -> ShowS # show :: Authentication -> String # showList :: [Authentication] -> ShowS # | |
Eq Authentication Source # | |
Defined in Database.Memcache.Types Methods (==) :: Authentication -> Authentication -> Bool # (/=) :: Authentication -> Authentication -> Bool # |
type Username = ByteString Source #
Username for authentication.
type Password = ByteString Source #
Password for authentication.
Operations
Get operations
get :: Cluster -> Key -> IO (Maybe (Value, Flags, Version)) Source #
Retrieve the value for the given key from Memcached.
gat :: Cluster -> Key -> Expiration -> IO (Maybe (Value, Flags, Version)) Source #
Get-and-touch: Retrieve the value for the given key from Memcached, and
also update the stored key-value pairs expiration time at the server. Use an
expiration value of 0
to store forever.
touch :: Cluster -> Key -> Expiration -> IO (Maybe Version) Source #
Update the expiration time of a stored key-value pair, returning its
version identifier. Use an expiration value of 0
to store forever.
Set operations
set :: Cluster -> Key -> Value -> Flags -> Expiration -> IO Version Source #
Store a new (or overwrite exisiting) key-value pair, returning its version
identifier. Use an expiration value of 0
to store forever.
cas :: Cluster -> Key -> Value -> Flags -> Expiration -> Version -> IO (Maybe Version) Source #
Store a key-value pair, but only if the version specified by the client
matches the Version of the key-value pair at the server. The version
identifier of the stored key-value pair is returned, or if the version match
fails, Nothing
is returned. Use an expiration value of 0
to store
forever.
add :: Cluster -> Key -> Value -> Flags -> Expiration -> IO (Maybe Version) Source #
Store a new key-value pair, returning it's version identifier. If the
key-value pair already exists, then fail (return Nothing
). Use an
expiration value of 0
to store forever.
replace :: Cluster -> Key -> Value -> Flags -> Expiration -> Version -> IO (Maybe Version) Source #
Update the value of an existing key-value pair, returning it's new version
identifier. If the key doesn't already exist, the fail and return Nothing.
Use an expiration value of 0
to store forever.
Modify operations
increment :: Cluster -> Key -> Initial -> Delta -> Expiration -> Version -> IO (Maybe (Word64, Version)) Source #
Increment a numeric value stored against a key, returning the incremented
value and the version identifier of the key-value pair. Use an expiration
value of 0
to store forever.
decrement :: Cluster -> Key -> Initial -> Delta -> Expiration -> Version -> IO (Maybe (Word64, Version)) Source #
Decrement a numeric value stored against a key, returning the decremented
value and the version identifier of the key-value pair. Use an expiration
value of 0
to store forever.
append :: Cluster -> Key -> Value -> Version -> IO (Maybe Version) Source #
Append a value to an existing key-value pair, returning the new version identifier of the key-value pair when successful.
prepend :: Cluster -> Key -> Value -> Version -> IO (Maybe Version) Source #
Prepend a value to an existing key-value pair, returning the new version identifier of the key-value pair when successful.
Delete operations
delete :: Cluster -> Key -> Version -> IO Bool Source #
Delete a key-value pair at the server, returning true if successful.
flush :: Cluster -> Maybe Expiration -> IO () Source #
Remove (delete) all currently stored key-value pairs from the cluster. The expiration value can be used to cause this flush to occur in the future rather than immediately.
Information operations
type StatResults = [(ByteString, ByteString)] Source #
StatResults are a list of key-value pairs.
stats :: Cluster -> Maybe Key -> IO [(Server, Maybe StatResults)] Source #
Return statistics on the stored key-value pairs at each server in the
cluster. The optional key can be used to select a different set of
statistics from the server than the default. Most Memcached servers support
"items"
, "slabs"
or "settings"
.
version :: Cluster -> IO ByteString Source #
Version returns the version string of the Memcached cluster. We just query one server and assume all servers in the cluster are the same version.
Errors
data MemcacheError Source #
All exceptions that a Memcached client may throw.
Constructors
OpError Status | Memcached operation error. |
ClientError ClientError | Error occuring on client side. |
ProtocolError ProtocolError | Errors occurring communicating with Memcached server. |
Instances
Exception MemcacheError Source # | |
Defined in Database.Memcache.Errors Methods toException :: MemcacheError -> SomeException # fromException :: SomeException -> Maybe MemcacheError # displayException :: MemcacheError -> String # | |
Show MemcacheError Source # | |
Defined in Database.Memcache.Errors Methods showsPrec :: Int -> MemcacheError -> ShowS # show :: MemcacheError -> String # showList :: [MemcacheError] -> ShowS # | |
Eq MemcacheError Source # | |
Defined in Database.Memcache.Errors Methods (==) :: MemcacheError -> MemcacheError -> Bool # (/=) :: MemcacheError -> MemcacheError -> Bool # |
The status (success or error) of a Memcached operation returned in a
Response
.
Constructors
NoError | Operation successful. |
ErrKeyNotFound | Key not found. |
ErrKeyExists | Key exists when not expected. |
ErrValueTooLarge | Value too large to store at server. |
ErrInvalidArgs | Invalid arguments for operation. |
ErrItemNotStored | Key-Value pair not stored at server (internal error). |
ErrValueNonNumeric | Value not numeric when increment or decrement requested. |
ErrUnknownCommand | Server doesn't know requested command. |
ErrOutOfMemory | Server out of memory. |
SaslAuthFail | SASL authentication failed. |
SaslAuthContinue | SASL authentication requires more steps. |
data ClientError Source #
Errors that occur on the client.
Constructors
NoServersReady | All servers are currently marked failed. |
Timeout | Timeout occurred sending request to server. |
Instances
Show ClientError Source # | |
Defined in Database.Memcache.Errors Methods showsPrec :: Int -> ClientError -> ShowS # show :: ClientError -> String # showList :: [ClientError] -> ShowS # | |
Eq ClientError Source # | |
Defined in Database.Memcache.Errors |
data ProtocolError Source #
Errors related to Memcached protocol and bytes on the wire.
Constructors
UnknownPkt | Received an unknown response packet. |
Fields | |
UnknownOp | Unknown Memcached operation. |
Fields | |
UnknownStatus | Unknown Memcached status field value. |
Fields | |
BadLength | Unexpected length of a Memcached field (extras, key, or value). |
Fields | |
WrongOp | Response packet is for a different operation than expected. |
Fields | |
UnexpectedEOF | Network socket closed without receiving enough bytes. |
Fields |
Instances
Show ProtocolError Source # | |
Defined in Database.Memcache.Errors Methods showsPrec :: Int -> ProtocolError -> ShowS # show :: ProtocolError -> String # showList :: [ProtocolError] -> ShowS # | |
Eq ProtocolError Source # | |
Defined in Database.Memcache.Errors Methods (==) :: ProtocolError -> ProtocolError -> Bool # (/=) :: ProtocolError -> ProtocolError -> Bool # |