Holumbus-Distribution-0.1.0: source/Holumbus/Distribution/DValue.hs
-- ----------------------------------------------------------------------------
{- |
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 ()
-}