- class IResource a where
- keyResource :: a -> String
- readResourceByKey :: String -> IO (Maybe a)
- writeResource :: a -> IO ()
- delResource :: a -> IO ()
- data Resources a b
- resources :: Resources a ()
- class Indexable a where
- class Serializable a where
- serialize :: a -> String
- deserialize :: String -> a
- defaultReadResource :: (Serializable a, Indexable a, Typeable a) => a -> IO (Maybe a)
- defaultReadResourceByKey :: (Serializable a, Indexable a) => String -> IO (Maybe a)
- defaultWriteResource :: (Serializable a, Indexable a) => a -> IO ()
- defaultDelResource :: Indexable a => a -> IO ()
Documentation
An IResource instance that must be defined for every object being cached. there are a set of implicit IResource instance trough utiliy classes (See below)
:: a | |
-> String | must be defined |
readResourceByKey :: String -> IO (Maybe a)Source
readResourceByKey
implements the database access and marshalling or of the object.
while the database access must be strict, the marshaling must be lazy if, as is often the case,
some parts of the object are not really accesed.
Moreover, if the object contains DBRefs, this avoids unnecesary cache lookups
this method is called inside atomically
blocks and thus may be interrupted without calling
Since STM transactions retry, readResourceByKey may be called twice in strange situations. So it must be idempotent, not only in the result but also in the effect in the database
writeResource :: a -> IO ()Source
the write operation in persistent storage. It must be strict.
Since STM transactions may retry, writeResource must be idempotent, not only in the result but also in the effect in the database
all the new obbects are writeen to the database on synchromization
so writeResource must not autocommit.
Commit code must be located in the postcondition. (see setConditions
)
delResource :: a -> IO ()Source
is called syncronously. It must autocommit
Resources data definition used by withSTMResources
Indexable is an utility class used to derive instances of IResource
Example:
data Person= Person{ pname :: String, cars :: [DBRef Car]} deriving (Show, Read, Typeable) data Car= Car{owner :: DBRef Person , cname:: String} deriving (Show, Read, Eq, Typeable)
Since Person and Car are instances of Read
ans Show
, by defining the Indexable
instance
will implicitly define the IResource instance for file persistence:
instance Indexable Person where key Person{pname=n} = "Person " ++ n instance Indexable Car where key Car{cname= n} = "Car " ++ n
class Serializable a whereSource
Serialize is an abstract serialization ionterface in order to define implicit instances of IResource. The deserialization must be as lazy as possible if deserialized objects contain DBRefs, lazy deserialization avoid unnecesary DBRef instantiations when they are not accessed, since DBRefs instantiations involve extra cache lookups For this reason serializationdeserialization is tofrom ordinary Strings serialization/deserialization are not performance critical in TCache
defaultReadResource :: (Serializable a, Indexable a, Typeable a) => a -> IO (Maybe a)Source
defaultReadResourceByKey :: (Serializable a, Indexable a) => String -> IO (Maybe a)Source
defaultWriteResource :: (Serializable a, Indexable a) => a -> IO ()Source
defaultDelResource :: Indexable a => a -> IO ()Source