TCache- Data caching and Persistent STM transactions




class IResource a whereSource

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


(Serializable a, Indexable a) => IResource a

Serializable, Indexable instances are implicit instances of IResource

(Typeable reg, Typeable a, Read reg, Show reg, Read a, Show a, Ord a, IResource reg) => IResource (Index reg a) 

data Resources a b Source

idempotentProperty k= do r <- readResourceByKey k r' <- readResourceByKey k return (r == r')

idempotentProperty :: (IResource a) => a -> IO Bool idempotentProperty x= do r <- readResourceByKey $ keyResource x r' <- readResourceByKey $ keyResource x return (r == r')

readResource :: IResource a => a-> IO (Maybe a) readResource x= readResourceByKey $ keyResource x

Resources data definition used by withSTMResources



forces a retry



toAdd :: [a]

resources to be inserted back in the cache

toDelete :: [a]

resources to be deleted from the cache and from permanent storage

toReturn :: b

result to be returned

resources :: Resources a ()Source

Empty resources: resources= Resources [] [] ()

class Indexable a whereSource

Indexable is an utility class used to derive instances of IResource


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


key :: a -> StringSource



:: a 
-> String

additional extension for default file paths. The default value is data/.


(Typeable reg, Typeable a) => Indexable (Index reg a) 

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


(Show a, Read a) => Serializable a

Read, Show, instances are implicit instances of Serializable

(IResource reg, Typeable reg, Ord a, Read reg, Read a, Show reg, Show a) => Serializable (Index reg a) 

defaultReadResource :: (Serializable a, Indexable a, Typeable a) => a -> IO (Maybe a)Source

Read, Show, instances are implicit instances of Serializable instance (Show a, Read a) => Serializable a where serialize= show deserialize= read