{-# LANGUAGE MultiParamTypeClasses , FlexibleInstances , UndecidableInstances #-} module Control.Workflow.Text.TextDefs where import Control.Workflow.IDynamic import Control.Workflow.GenSerializer import Data.RefSerialize import System.IO.Unsafe import Data.TCache.DefaultPersistence(Indexable(..)) import Data.IORef import Unsafe.Coerce import Data.ByteString.Lazy.Char8 as B hiding (index) import Control.Workflow.Stat import Data.Map as M import Control.Concurrent import Data.TCache instance Serialize a => Serializer ST ST a where serial = showp deserial = readp instance RunSerializer ST ST where runSerial = runW runDeserial = runR instance Serialize a => DynSerializer ST ST a where serialM = showps fromDynData s c= runRC c readp s instance Serialize IDynamic where showp (IDyn t)= case unsafePerformIO $ readIORef t of DRight x -> do insertString $ pack dynPrefix showpx <- unsafeCoerce $ serialM x showpText . fromIntegral $ B.length showpx insertString showpx DLeft (showpx,_) -> -- error $ "IDynamic not reified :: "++ unpack showpx do insertString $ pack dynPrefix showpText 0 readp = do symbol dynPrefix n <- readpText s <- takep n c <- getContext return . IDyn . unsafePerformIO . newIORef $ DLeft ( s, c) "IDynamic" instance Serialize Stat where showp (Running map)= do insertString $ pack "Running" showp $ Prelude.map (\(k,(w,_)) -> (k,w)) $ M.toList map showp stat@( Stat wfName state index recover versions _ )=do insertString $ pack "Stat" showpText wfName showpText state showpText index showpText recover showp versions readp = choice [rStat, rWorkflows] where rStat= do symbol "Stat" wfName <- stringLiteral state <- integer >>= return . fromIntegral index <- integer >>= return . fromIntegral recover <- bool versions <- readp return $ Stat wfName state index recover versions Nothing "Stat" rWorkflows= do symbol "Running" list <- readp return $ Running $ M.fromList $ Prelude.map(\(k,w)-> (k,(w,Nothing))) list "RunningWoorkflows" instance Serialize ThreadId where showp th= insertString . pack $ show th readp = (readp :: ST ByteString) >> (return . unsafePerformIO . forkIO $ return ()) newtype Pretty = Pretty Stat instance Show Pretty where show= unpack . runW . sp where sp (Pretty (Stat wfName state index recover versions _ ))= do insertString $ pack "Workflow name= " showp wfName insertString $ pack "\n" showElem $ Prelude.reverse $ (Prelude.zip ( Prelude.reverse [1..] ) versions ) showElem :: [(Int,IDynamic)] -> ST () showElem [] = insertChar '\n' showElem ((n, dyn):es) = do showp $ pack "Step " showp n showp $ pack ": " showp dyn insertChar '\n' showElem es statPrefix= "Stat#" instance Indexable Stat where key s@Stat{wfName=name}= statPrefix ++ name key (Running _)= keyRunning defPath= const "WorkflowState/Text/" wFRefStr = "WFRef" instance Serialize (WFRef a) where showp (WFRef n ref)= do insertString $ pack wFRefStr showp n showp $ keyObjDBRef ref readp= do symbol wFRefStr n <- readp k <- readp return . WFRef n $ getDBRef k -- | print the state changes along the workflow, that is, all the intermediate results printHistory :: Stat -> IO () printHistory stat= do Prelude.putStrLn . show $ Pretty stat Prelude.putStrLn "-----------------------------------"