packages feed

Workflow 0.8.0.6 → 0.8.0.7

raw patch · 3 files changed

+61/−47 lines, 3 filesdep +MonadCatchIO-transformersdep −MonadCatchIO-mtlPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: MonadCatchIO-transformers

Dependencies removed: MonadCatchIO-mtl

API changes (from Hackage documentation)

- Control.Workflow: delWF1 :: MonadIO m => String -> m ()
- Control.Workflow: killWF1 :: MonadIO m => String -> m ()
+ Control.Workflow: getState :: (Monad m, MonadIO m, Indexable a, Serialize a, Typeable a) => String -> x -> a -> m (Either WFErrors (String, x, Stat))
+ Control.Workflow: instance [overlap ok] (Monad m, Functor m) => Applicative (Workflow m)
+ Control.Workflow: runWF1 :: MonadIO m => String -> WF Stat m b -> Stat -> Bool -> m b
+ Control.Workflow.Stat: Running :: (Map String (String, Maybe ThreadId)) -> Stat
+ Control.Workflow.Stat: Stat :: DBRef Stat -> String -> Int -> Bool -> Maybe Integer -> Integer -> (Context, ByteString) -> [(Int, (IDynamic, Bool))] -> [IDynamic] -> Stat
+ Control.Workflow.Stat: WF :: (s -> m (s, l)) -> WF s m l
+ Control.Workflow.Stat: WFRef :: !Int -> !(DBRef Stat) -> WFRef a
+ Control.Workflow.Stat: context :: Stat -> (Context, ByteString)
+ Control.Workflow.Stat: data Stat
+ Control.Workflow.Stat: data WF s m l
+ Control.Workflow.Stat: data WFRef a
+ Control.Workflow.Stat: fr :: String -> IO (Maybe ByteString)
+ Control.Workflow.Stat: getHeader :: STR ([Char], Int, Maybe Integer, Integer, [a], (Context, ByteString))
+ Control.Workflow.Stat: hReadFile :: Handle -> IO ByteString
+ Control.Workflow.Stat: header :: Stat -> STW ()
+ Control.Workflow.Stat: instance [overlap ok] (Show a, Read a) => Serialize a
+ Control.Workflow.Stat: instance [overlap ok] IResource Stat
+ Control.Workflow.Stat: instance [overlap ok] Indexable (WFRef a)
+ Control.Workflow.Stat: instance [overlap ok] Read (WFRef a)
+ Control.Workflow.Stat: instance [overlap ok] Serialize (WFRef a)
+ Control.Workflow.Stat: instance [overlap ok] Serialize Stat
+ Control.Workflow.Stat: instance [overlap ok] Serialize ThreadId
+ Control.Workflow.Stat: instance [overlap ok] Show (WFRef a)
+ Control.Workflow.Stat: instance [overlap ok] Typeable Stat
+ Control.Workflow.Stat: instance [overlap ok] Typeable1 WFRef
+ Control.Workflow.Stat: keyRunning :: String
+ Control.Workflow.Stat: keyWF :: Indexable a => String -> a -> String
+ Control.Workflow.Stat: lastActive :: Stat -> Integer
+ Control.Workflow.Stat: lenLen :: Int64
+ Control.Workflow.Stat: pathWFlows :: [Char]
+ Control.Workflow.Stat: readHeader :: ByteString -> Handle -> IO (Maybe ([Char], Int, Maybe Integer, Integer, [a], (Context, ByteString)))
+ Control.Workflow.Stat: recover :: Stat -> Bool
+ Control.Workflow.Stat: references :: Stat -> [(Int, (IDynamic, Bool))]
+ Control.Workflow.Stat: safe :: FilePath -> (Handle -> IO a) -> IO a
+ Control.Workflow.Stat: self :: Stat -> DBRef Stat
+ Control.Workflow.Stat: showHistory :: Stat -> ByteString
+ Control.Workflow.Stat: showp1 :: IDynamic -> STW ()
+ Control.Workflow.Stat: st :: WF s m l -> s -> m (s, l)
+ Control.Workflow.Stat: stFName :: IResource a => a -> [Char]
+ Control.Workflow.Stat: stat0 :: Stat
+ Control.Workflow.Stat: statPrefix :: [Char]
+ Control.Workflow.Stat: statPrefix1 :: [Char]
+ Control.Workflow.Stat: state :: Stat -> Int
+ Control.Workflow.Stat: timeout :: Stat -> Maybe Integer
+ Control.Workflow.Stat: versions :: Stat -> [IDynamic]
+ Control.Workflow.Stat: wFRefStr :: [Char]
+ Control.Workflow.Stat: wfName :: Stat -> String

Files

Control/Workflow.hs view
@@ -71,7 +71,7 @@   -"Control.Workflow.Patterns"  contains higuer level workflow patters of multiuser workflows+"Control.Workflow.Patterns"  contains higher level workflow patterns for handling multiple workflows  "Control.Workflow.Configuration" permits the use of workflows for configuration purposes @@ -138,8 +138,6 @@ , killWF , delWF , killThreadWF1-, killWF1-, delWF1 , delWFHistory , delWFHistory1 -- * Log writing policy@@ -148,6 +146,10 @@ -- * Print log history , showHistory , isInRecover+-- * Low leve, internal use+, runWF1+, getState+ )  where@@ -155,6 +157,7 @@ import Prelude hiding (catch) import System.IO.Unsafe import Control.Monad(when,liftM)+import Control.Applicative import qualified Control.Exception as CE (Exception,AsyncException(ThreadKilled), SomeException, ErrorCall, throwIO, handle,finally,catch,block,unblock) import Control.Concurrent -- (forkIO,threadDelay, ThreadId, myThreadId, killThread) import Control.Concurrent.STM@@ -188,9 +191,8 @@ import System.Mem.StableName import Control.Workflow.Stat -import Debug.Trace-a !> b= trace b a-+--import Debug.Trace+--(!>)= flip trace  type Workflow m = WF  Stat  m   -- not so scary @@ -249,6 +251,15 @@           where      plift = step +instance  (Monad m, Functor m) => Applicative  (Workflow m) where+   pure x= return x+   WF f <*> WF g= WF $ \s ->  do+        (s1, k) <- f s+        (s2, x) <- g s1
+        return  (s2,k x)+++ -- |  An instance of MonadTrans is an instance of PMonadTrans instance (MonadTrans t, Monad m) => PMonadTrans t m a where     plift= Control.Monad.Trans.lift@@ -262,7 +273,7 @@    liftIO= unsafeIOtoWF  -{- | adapted from the @MonadCatchIO-mtl@ package. However, in tis case is needed to express serializable constraints about the  returned values,+{- | Adapted from the @MonadCatchIO-mtl@ package. However, in this case it is needed to express serializable constraints about the  returned values, so the usual class definitions for lifting IO functions are not suitable. -} @@ -293,8 +304,7 @@      expwf <- step $ getTempName      excwf <- step $ getTempName      step $ do-        ex <- CMC.catch (exec1d expwf exp >>= return . Right-                                           ) $ \e-> return $ Left e+        ex <- CMC.catch (exec1d expwf exp >>= return . Right ) $ \e-> return $ Left e          case ex of            Right r -> return r                -- All right@@ -322,7 +332,6 @@  instance  (HasFork io, MonadIO io           , CMC.MonadCatchIO io)-           => HasFork (WF Stat  io) where    fork f = do     (r,info@(WFInfo str finished status)) <- stepWFRef $ getTempName >>= \n -> return(WFInfo n False  Nothing)@@ -414,8 +423,7 @@     case v of       Left err -> CMC.throw err       Right (name, f, stat) -> do-         r <- runWF1 name f  stat False-         return  r+         runWF1 name f  stat False          `CMC.catch`            (\(e :: CE.SomeException) -> liftIO $ do@@ -470,7 +478,7 @@ --                                      !> (unpack $ runW $ showp $  versions s) --                                      !> (show $ references s) --                                      !> (show $ "recover="++ show( recover s))---                                      !> "^^^^^^^^^^^^^^^^^^^^"+--                                      !> "^^^^^^^^^^^^^^^^^^^"         if recovers && not (L.null versionss)           then             return (s{versions=L.tail versionss }, fromIDyn $ L.head versionss )@@ -506,6 +514,7 @@ --undoStep :: Monad m => Workflow m () --undoStep= WF $ \s@Stat{..} -> return(s{state=state-1, versions= L.tail versions},()) +-- | True if the workflow in recovery mode, reading the log to recover the process state isInRecover :: Monad m => Workflow m Bool isInRecover = WF(\s@Stat{..} ->      if recover  && not (L.null  versions ) then  return(s,True )@@ -585,14 +594,14 @@ -- | Start or continue a workflow  . --  'WFErrors' and exceptions are returned as @Left err@ (even if they were triggered as exceptions). -- Other exceptions are returned as @Left (Exception e)@--- use `killWF` or `delWF` in case of erro to clear the log.+-- use `killWF` or `delWF` in case of error to clear the log. start     :: ( CMC.MonadCatchIO m        , MonadIO m        , Indexable a        , Serialize a        , Typeable a)-    => String                        -- ^ name thar identifies the workflow.+    => String                        -- ^ name that identifies the workflow.     -> (a -> Workflow m b)           -- ^ workflow to execute     -> a                             -- ^ initial value (ever use the initial value for restarting the workflow)     -> m  (Either WFErrors b)        -- ^ result of the computation@@ -606,12 +615,12 @@            (\(e :: WFErrors) -> do                  let name=  keyWF namewf v                  clearRunningFlag name-                 return $ Left e)+                 return $ Left e )     `CMC.catch`            (\(E.ErrorCall msg) ->do                  let name=  keyWF namewf v                  clearRunningFlag name-                 return . Left $ WFException msg)+                 return . Left $ WFException msg )     `CMC.catch`            (\(e :: CE.SomeException) ->  liftIO $ do                  let name=  keyWF namewf v@@ -677,13 +686,13 @@              safeIOToSTM $ delResource stat1 >> writeResource stat1              writeDBRef tvRunningWfs . Running $ M.insert key (namewf,Just mythread) map              writeDBRef sref stat1-             return $ Right (key, f, stat1)+             return $ Right (key, f, stat1)   -- !> "NEW WF"             Just (wf, started) ->               -- a workflow has been initiated for this object              if isJust started-                then return $ Left AlreadyRunning                       -- !> "already running"-                else  do            -- has been running but not running now-                   mst <- readDBRef sref+                then return $ Left AlreadyRunning                  -- !> "already running"+                else  do+                   mst <- readDBRef sref                           -- !> "has been running but not running now"                    stat' <- case mst of                           Nothing -> return stat1 -- error $ "getState: Workflow not found: "++ key                           Just s' -> do@@ -698,7 +707,7 @@                              if isJust (timeout s)                               then do                                   tnow <- unsafeIOToSTM getTimeSeconds-                                  if lastActive s+ fromJust(timeout s) > tnow   -- !>("lastActive="++show (lastActive s) ++ "tnow="++show tnow)+                                  if lastActive s+ fromJust(timeout s) > tnow    -- !>("lastActive="++show (lastActive s) ++ "tnow="++show tnow)                                        then                                          return s{recover= True,timeout=Nothing}                                        else@@ -723,7 +732,7 @@   runWF1 n f s clear=  do-   (s', v')  <-  st f s{versions= L.tail $ versions s} -- !> (show $ versions s)+   (s', v')  <-  st f s{versions= L.tail $ versions s}    liftIO $ if clear then clearFromRunningList n                      else clearRunningFlag n >> return ()    return  v'@@ -732,8 +741,9 @@    -- eliminate the thread from the list of running workflows but leave the state    clearFromRunningList n = atomicallySync $ do       Just(Running map) <-  readDBRef tvRunningWfs           -- !> "clearFormRunning"-      writeDBRef tvRunningWfs . Running $ M.delete   n   map -- `debug` "clearFromRunningList"+      writeDBRef tvRunningWfs . Running $ M.delete   n   map --      flushDBRef (getDBRef n ::  DBRef Stat)+ -- | Start or continue a workflow  from a list of workflows  with exception handling. --  see 'start' for details about exception and error handling startWF@@ -820,7 +830,7 @@ -- | Delete the history of a workflow. -- Be sure that this WF has finished. ---{-# DEPRECATED delWFHistory, delWFHistory1 "use delWF and delWF1 instead" #-}+--{-# DEPRECATED delWFHistory, delWFHistory1 "use delWF  instead" #-}  delWFHistory name1 x = do       let name= keyWF name1 x@@ -871,13 +881,16 @@  -- | Kill the process (if running) and drop it from the list of --  restart-able workflows. Its state history remains , so it can be inspected with---  `getWfHistory` `printWFHistory` and so on+--  `getWfHistory` `printWFHistory` and so on.+--+-- When the workflow has been called with no parameter, use: ()+-- killWF :: (Indexable a,MonadIO m) => String -> a -> m () killWF name1 x= do        let name= keyWF name1 x        killWF1 name --- | A version of `KillWF` for workflows started wit no parameter by `exec1`+ killWF1 :: MonadIO m => String  -> m () killWF1 name = do        map <- killThreadWFm name@@ -886,6 +899,8 @@  -- | Delete the WF from the running list and delete the workflow state from persistent storage. --  Use it to perform cleanup if the process has been killed.+--+-- When the workflow has been called with no parameter, use: () delWF :: ( Indexable a          , MonadIO m          , Typeable a)@@ -895,21 +910,19 @@   delWF1 name  --- | A version of `delWF` for workflows started wit no parameter by `exec1`-delWF1 :: MonadIO m=> String  -> m()-delWF1 name= liftIO $ do-  mrun <- atomically $ readDBRef tvRunningWfs++delWF1 :: MonadIO m => String  -> m()+delWF1 name= liftIO $ atomicallySync $ do+  mrun <-  readDBRef tvRunningWfs   case mrun of     Nothing -> return()     Just (Running map) -> do-      atomicallySync . writeDBRef tvRunningWfs . Running $! M.delete   name   map-      delWFHistory1 name--+       writeDBRef tvRunningWfs . Running $! M.delete   name   map+       delDBRef  (getDBRef $ keyResource $ stat0{wfName= name} :: DBRef Stat)   clearRunningFlag name= liftIO $ atomically $ do-  Running map <-readDBRef tvRunningWfs `onNothing` error ( "clearRunningFLag: non existing workflows" ++ name)+  Running map <- readDBRef tvRunningWfs `onNothing` error ( "clearRunningFLag: no workflow list" ++ name)   case M.lookup  name map of     Just(_, Nothing) -> return (map,Nothing)     Just(v, Just th) -> do@@ -1002,7 +1015,7 @@         Just (r,_) -> return . Just $ fromIDyn r         Nothing -> do           let  n1=  if recover st then n else state st - n-          return . Just . fromIDyn $ versions st !! n1 !> (show (L.length $ versions st) ++ " "++ show n1)+          return . Just . fromIDyn $ versions st !! n1         -- !> (show (L.length $ versions st) ++ " "++ show n1)  --      flushDBRef ref !> "readWFRef" --      st <- readDBRef ref `justifyM` (error $ "readWFRef: reference has been deleted from storaga: "++ show ref)@@ -1073,7 +1086,6 @@              =>String -> a -> a -> m () moveState wf t t'=  liftIO $ do      atomicallySync $ do-            mrun <-  readDBRef tvRunningWfs            case mrun of                 Nothing -> return()@@ -1087,9 +1099,10 @@      where      n = keyWF wf t      n'= keyWF wf t'-     change n  [Nothing] = error $ "moveState: Workflow not found: "++ show n-     change n [Just s] = resources{toAdd= [ s{wfName=n',versions = toIDyn t': L.tail( versions s) }]-                                             ,toDelete=[s]}+     change n [Nothing]= error $ "moveState: Workflow not found: "++ show n+     change n [Just s] = resources{toAdd= [s{wfName=n'+                                            ,versions = toIDyn t': L.tail( versions s) }]+                                  ,toDelete=[s]}   
Control/Workflow/Stat.hs view
@@ -142,7 +142,7 @@ pathWFlows=  (defPath (1:: Int)) ++ "workflow/" stFName st = pathWFlows ++ keyResource st -Persist fr fw fd = defaultPersist+Persist fr fw fd = filePersist  --nheader= "/header" --nlog= "/log"@@ -160,7 +160,7 @@    delResource st= fd  (stFName st) -- removeFile (stFName st)  `catch`\(e :: IOError) -> return () -  writeResource runn@(Running _)=  B.writeFile (stFName runn)  . runW $ showp runn+  writeResource runn@(Running _)=  fw{- B.writeFile -} (stFName runn)  . runW $ showp runn  --   writeResource stat@Stat{..}
Workflow.cabal view
@@ -1,5 +1,5 @@ name: Workflow-version: 0.8.0.6+version: 0.8.0.7 cabal-version: >= 1.6 build-type: Simple license: BSD3@@ -24,7 +24,7 @@              See "Control.Workflow" for details              .              In this release:-             * start and startWF exception control fixed+             * adapted to the changes in default persistence in TCache  category: Control, Workflow @@ -38,7 +38,7 @@   library-    build-depends: MonadCatchIO-mtl -any, RefSerialize ==0.3.1.* ,+    build-depends: MonadCatchIO-transformers -any, RefSerialize ==0.3.1.* ,                    TCache -any && <1.0, base >=4 && <5, binary -any, bytestring -any,                    containers -any, directory -any, extensible-exceptions -any,                     mtl -any, old-time -any, stm >2, vector -any@@ -46,13 +46,14 @@     exposed-modules: Control.Workflow                      Control.Workflow.Configuration                      Control.Workflow.Patterns+                     Control.Workflow.Stat     exposed: True     buildable: True     extensions: OverlappingInstances UndecidableInstances                 MultiParamTypeClasses ExistentialQuantification                 TypeSynonymInstances RecordWildCards DeriveDataTypeable     hs-source-dirs: .-    other-modules: Control.Workflow.Stat+    other-modules:   source-repository head