{-# LANGUAGE MultiParamTypeClasses , FlexibleInstances , ScopedTypeVariables #-} module Control.Workflow.Binary.BinDefs where import Control.Workflow.GenSerializer import Control.Workflow.IDynamic import Control.Workflow.Stat import Data.TCache.DefaultPersistence(Indexable(..)) import Data.Binary import Data.Binary.Put import Data.Binary.Get import System.IO.Unsafe import Data.IORef import Data.ByteString.Lazy.Char8 as B hiding (index) import Data.Map as M import Control.Concurrent(ThreadId,forkIO) import Data.Typeable import Data.TCache instance Binary a => Serializer PutM Get a where serial = put deserial = get instance RunSerializer PutM Get where runSerial = runPut runDeserial = runGet instance Binary a => DynSerializer PutM Get a --instance TwoSerializer PutM Get PutM Get () () instance Binary IDynamic where put (IDyn t) = case unsafePerformIO $ readIORef t of DRight x -> put . runSerial $ serial x DLeft (s, _) -> put s get = do s <- get return $ IDyn . unsafePerformIO . newIORef $ DLeft (s, (undefined, pack "")) instance Binary Stat where put (Running map)= do put (0 :: Word8) put $ Prelude.map (\(k,(w,_)) -> (k,w)) $ M.toList map put (Stat wfName state index recover versions _) = do put (1 :: Word8) put wfName put state put index put recover put versions get = do t <- get :: Get Word8 case t of 0 -> do list <- get return . Running . M.fromList $ Prelude.map(\(k,w)-> (k,(w,Nothing))) list 1 -> do wfName <- get state <- get index <- get recover <- get versions <- get return $ Stat wfName state index recover versions Nothing instance Binary ThreadId where put _= put $ pack "th" get = get >>= \(_ :: String) -> return $ unsafePerformIO . forkIO $ return () instance Binary (WFRef a) where put (WFRef n ref)= do put n put $ keyObjDBRef ref get= do n <- get k <- get return . WFRef n $ getDBRef k instance Indexable Stat where key s@Stat{wfName=name}= "Stat#" ++ name key (Running _)= keyRunning defPath= const "WorkflowState/bin/"