-- ---------------------------------------------------------------------------- {- | Module : Holumbus.Distribution.DValue Copyright : Copyright (C) 2010 Stefan Schmidt License : MIT Maintainer : Stefan Schmidt (stefanschmidt@web.de) Stability : experimental Portability: portable Version : 0.1 This module offers the distrubted value datatype. A DValue is like a distributed MVar, but is can only be set once on the local node. If the value is set, it cannot be changed any more. I don't know if this is useful at all, so the implementation is not quite finished an some things could be improved. -} -- ---------------------------------------------------------------------------- module Holumbus.Distribution.DValue ( -- * datatypes DValue -- * creating and closing a DValue , newDValue , newRemoteDValue , closeDValue -- * access a DValue , getDValue -- , flushDValue ) where import Control.Concurrent.MVar import Data.Binary import Holumbus.Distribution.DMVar -- localLogger :: String --localLogger = "Holumbus.Distribution.DValue" data DValue a = DValueLocal (DMVar a) | DValueRemote (DMVar a) (MVar a) -- | Creates new DValue on the local DNode. The first parameter -- is the name of the value which could be used in other processes to -- access this stream. If you leave it empty, a random Id will be created. newDValue :: (Binary a) => String -> a -> IO (DValue a) newDValue s a = do dv <- newDMVar s a return (DValueLocal dv) -- | Creates a new DValue. -- The first parameter is the name of the resource and the second one -- the name of the node. newRemoteDValue :: String -> String -> IO (DValue a) newRemoteDValue r n = do dv <- newRemoteDMVar r n lv <- newEmptyMVar return (DValueRemote dv lv) -- | Closes a DValue. closeDValue :: (DValue a) -> IO () closeDValue (DValueLocal dv) = do closeDMVar dv closeDValue (DValueRemote dv _) = do closeDMVar dv -- | Gets value. It will only access the network on the first -- time and my throw an exception. It returns always (Just a) -- but this may change in the future, so the type sticks to (Maybe a) getDValue :: (Binary a) => DValue a -> IO (Maybe a) getDValue (DValueLocal dv) = do a <- readDMVar dv return (Just a) getDValue (DValueRemote dv lv) = do e <- isEmptyMVar lv if e then do --TODO exception handling here... a <- readDMVar dv putMVar lv a return (Just a) else do a <- readMVar lv return (Just a) {- flushDValue :: DValue a -> IO () flushDValue (DValueLocal _) = return () flushDValue (DValueRemote _ lv) = do e <- isEmptyMVar lv if e then return () else do _ <- takeMVar lv return () -}