-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Workflows with arrows
--
-- An arrow with resumable computations and logging
@package funflow
@version 1.3.2
-- | Various varieties of free arrow constructions.
--
-- For all of these constructions, there are only two important
-- functions: - eval evaluates the free arrow in the context of
-- another arrow. - effect lifts the underlying effect into the
-- arrow.
--
-- The class FreeArrowLike, which is not exported from this
-- module, exists to allow these to be defined generally.
--
-- This module also defines some arrow combinators which are not exposed
-- by the standard arrow library.
module Control.Arrow.Free
-- | Freely generated arrows over an effect.
data Free eff a b
-- | Freely generated ArrowChoice over an effect.
data Choice eff a b
-- | Freely generated arrows with both choice and error handling.
data ErrorChoice ex eff a b
effect :: FreeArrowLike fal => eff a b -> fal eff a b
eval :: forall eff arr a b. (FreeArrowLike fal, ((Ctx fal) arr)) => (eff ~> arr) -> fal eff a b -> arr a b
-- | ArrowError represents those arrows which can catch exceptions within
-- the processing of the flow.
class ArrowError ex a
catch :: ArrowError ex a => a e c -> a (e, ex) c -> a e c
-- | Map an arrow over a list.
mapA :: ArrowChoice a => a b c -> a [b] [c]
-- | Map an arrow over a list, forcing sequencing between each element.
mapSeqA :: ArrowChoice a => a b c -> a [b] [c]
-- | Filter a list given an arrow filter
filterA :: ArrowChoice a => a b Bool -> a [b] [b]
-- | A natural transformation on type constructors of two arguments.
type x ~> y = forall a b. x a b -> y a b
instance Control.Category.Category (Control.Arrow.Free.ErrorChoice ex eff)
instance Control.Arrow.Arrow (Control.Arrow.Free.ErrorChoice ex eff)
instance Control.Arrow.ArrowChoice (Control.Arrow.Free.ErrorChoice ex eff)
instance Control.Arrow.Free.ArrowError ex (Control.Arrow.Free.ErrorChoice ex eff)
instance Control.Arrow.Free.FreeArrowLike (Control.Arrow.Free.ErrorChoice ex)
instance (Control.Arrow.Arrow (Control.Arrow.Kleisli m), GHC.Exception.Exception ex, Control.Monad.Catch.MonadCatch m) => Control.Arrow.Free.ArrowError ex (Control.Arrow.Kleisli m)
instance Control.Category.Category (Control.Arrow.Free.Choice eff)
instance Control.Arrow.Arrow (Control.Arrow.Free.Choice eff)
instance Control.Arrow.ArrowChoice (Control.Arrow.Free.Choice eff)
instance Control.Arrow.Free.FreeArrowLike Control.Arrow.Free.Choice
instance Control.Category.Category (Control.Arrow.Free.Free eff)
instance Control.Arrow.Arrow (Control.Arrow.Free.Free eff)
instance Control.Arrow.Free.FreeArrowLike Control.Arrow.Free.Free
instance forall k (a :: k -> GHC.Types.Constraint) (x :: k) (b :: k -> GHC.Types.Constraint). (a x, b x) => Control.Arrow.Free.Join a b x
-- | Asynchronous arrows over monads with MonadBaseControl IO, using
-- lifted-async.
module Control.Arrow.Async
newtype AsyncA m a b
AsyncA :: a -> m b -> AsyncA m a b
[runAsyncA] :: AsyncA m a b -> a -> m b
-- | Lift an AsyncA through a monad transformer of the underlying monad.
liftAsyncA :: (MonadTrans t, Monad m) => AsyncA m i o -> AsyncA (t m) i o
instance GHC.Base.Monad m => Control.Category.Category (Control.Arrow.Async.AsyncA m)
instance Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO m => Control.Arrow.Arrow (Control.Arrow.Async.AsyncA m)
instance Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO m => Control.Arrow.ArrowChoice (Control.Arrow.Async.AsyncA m)
instance (GHC.Exception.Exception ex, Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO m, Control.Monad.Catch.MonadCatch m) => Control.Arrow.Free.ArrowError ex (Control.Arrow.Async.AsyncA m)
-- | A Diagram is a representation of an arrow with labels. No computation
-- is actually performed by a diagram, it just carries around a
-- description. We explot the fact that in 7.10, everything is typeable
-- to label the incoming and outgoing node types.
module Control.Funflow.Diagram
newtype NodeProperties
NodeProperties :: [Text] -> NodeProperties
[labels] :: NodeProperties -> [Text]
emptyNodeProperties :: NodeProperties
data Diagram ex a b
[Node] :: NodeProperties -> Proxy a -> Proxy b -> Diagram ex a b
[Seq] :: Diagram ex a b -> Diagram ex b c -> Diagram ex a c
[Par] :: Diagram ex a b -> Diagram ex c d -> Diagram ex (a, c) (b, d)
[Fanin] :: Diagram ex a c -> Diagram ex b c -> Diagram ex (Either a b) c
[Catch] :: Diagram ex a b -> Diagram ex (a, ex) b -> Diagram ex a b
-- | Construct a labelled node
node :: forall arr a b ex. Arrow arr => arr a b -> [Text] -> (Diagram ex) a b
instance Control.Category.Category (Control.Funflow.Diagram.Diagram ex)
instance Control.Arrow.Arrow (Control.Funflow.Diagram.Diagram ex)
instance Control.Arrow.ArrowChoice (Control.Funflow.Diagram.Diagram ex)
instance Control.Arrow.Free.ArrowError ex (Control.Funflow.Diagram.Diagram ex)
-- | Thread and process write lock.
--
-- Allows synchronisation between threads and processes. Uses an
-- MVar for synchronisation between threads and fcntl write locks
-- for synchronisation between processes.
--
-- Only ever have one Lock object per lock file per process!
module Control.Funflow.Lock
-- | Thread and process write lock.
--
-- Only ever have one Lock object per lock file per process!
data Lock
-- | Open the lock file and create a lock object.
--
-- This does not acquire the lock.
--
-- Only ever have one Lock object per lock file per process!
openLock :: Path Abs Dir -> IO Lock
-- | Close the lock file.
--
-- Does not release the lock.
--
-- Blocks if the lock is taken.
closeLock :: Lock -> IO ()
-- | Acquire the lock for the duration of the given action and release
-- after.
withLock :: Lock -> IO a -> IO a
-- | Dedicated module for orphan instances.
module Control.Funflow.Orphans
instance Data.Store.Impl.Store (Path.Internal.Path Path.Abs Path.File)
instance Data.Store.Impl.Store (Path.Internal.Path Path.Abs Path.Dir)
instance Data.Store.Impl.Store (Path.Internal.Path Path.Rel Path.File)
instance Data.Store.Impl.Store (Path.Internal.Path Path.Rel Path.Dir)
-- | ContentHashable provides a hashing function suitable for use in
-- the Funflow content store.
--
-- This behaves as does a normal hashing function on Haskell types.
-- However, on path types, this instead calculates a hash based on the
-- contents of the file or directory referenced.
--
-- We also export the ExternallyAssuredFile and
-- ExternallyAssuredDirectory types. These instead use the path,
-- file size and modification time to control the hash.
module Control.Funflow.ContentHashable
data ContentHash
toBytes :: ContentHash -> ByteString
fromBytes :: ByteString -> Maybe ContentHash
class Monad m => ContentHashable m a
-- | Update a hash context based on the given value.
--
-- See hashUpdate.
--
-- XXX: Consider swapping the arguments.
contentHashUpdate :: ContentHashable m a => Context SHA256 -> a -> m (Context SHA256)
-- | Update a hash context based on the given value.
--
-- See hashUpdate.
--
-- XXX: Consider swapping the arguments.
contentHashUpdate :: (ContentHashable m a, Generic a, GContentHashable m (Rep a)) => Context SHA256 -> a -> m (Context SHA256)
-- | Generate hash of the given value.
--
-- See hash.
contentHash :: ContentHashable m a => a -> m ContentHash
-- | Update hash context based on binary contents of the given file.
contentHashUpdate_binaryFile :: Context SHA256 -> FilePath -> IO (Context SHA256)
-- | Update hash context based on ByteArray# by copying into a newly
-- allocated Bytes and updating the hash context from there.
--
-- XXX: byteArrayContents# :: ByteArray# ->
-- Addr# could be used together with MemView instead.
-- However, byteArrayContents# explicitly says, that it is only
-- safe to use on a pinned ByteArray#.
contentHashUpdate_byteArray# :: ByteArray# -> Int -> Int -> Context SHA256 -> Context SHA256
-- | Update hash context based on a type's Fingerprint.
--
-- The fingerprint is constructed from the library-name, module-name, and
-- name of the type itself.
contentHashUpdate_fingerprint :: (Monad m, Typeable a) => Context SHA256 -> a -> m (Context SHA256)
-- | Update hash context by combining contentHashUpdate_fingerprint
-- and contentHashUpdate_storable. Intended for primitive types
-- like Int.
contentHashUpdate_primitive :: (Monad m, Typeable a, Storable a) => Context SHA256 -> a -> m (Context SHA256)
-- | Update hash context based on binary in memory representation due to
-- Storable.
--
-- XXX: Do we need to worry about endianness?
contentHashUpdate_storable :: (Monad m, Storable a) => Context SHA256 -> a -> m (Context SHA256)
-- | Path to a regular file
--
-- Only the file's content and its executable permission is taken into
-- account when generating the content hash. The path itself is ignored.
newtype FileContent
FileContent :: (Path Abs File) -> FileContent
-- | Path to a directory
--
-- Only the contents of the directory and their path relative to the
-- directory are taken into account when generating the content hash. The
-- path to the directory is ignored.
newtype DirectoryContent
DirectoryContent :: (Path Abs Dir) -> DirectoryContent
-- | Path to a file to be treated as _externally assured_.
--
-- An externally assured file is handled in a somewhat cheating
-- way by funflow. The ContentHashable instance for such assumes
-- that some external agent guarantees the integrity of the file being
-- referenced. Thus, rather than hashing the file contents, we only
-- consider its (absolute) path, size and modification time, which can be
-- rapidly looked up from filesystem metadata.
--
-- For a similar approach, see the instance for ObjectInBucket
-- in Control.Funflow.AWS.S3, where we exploit the fact that S3 is
-- already content hashed to avoid performing any hashing.
newtype ExternallyAssuredFile
ExternallyAssuredFile :: (Path Abs File) -> ExternallyAssuredFile
-- | Path to a directory to be treated as _externally assured_.
--
-- For an externally assured directory, we _do_ traverse its contents and
-- verify those as we would externally assured files, rather than just
-- relying on the directory path. Doing this traversal is pretty cheap,
-- and it's quite likely for directory contents to be modified without
-- modifying the contents.
--
-- If an item in the directory cannot be read due to lacking permissions,
-- then it will be ignored and not included in the hash. If the flow does
-- not have permissions to access the contents of a subdirectory, then
-- these contents cannot influence the outcome of a task and it is okay
-- to exclude them from the hash. In that case we only hash the name, as
-- that could influence the outcome of a task.
newtype ExternallyAssuredDirectory
ExternallyAssuredDirectory :: (Path Abs Dir) -> ExternallyAssuredDirectory
-- | File path appropriate encoding of a hash
encodeHash :: ContentHash -> ByteString
-- | Inverse of encodeHash if given a valid input.
--
--
-- decodeHash (encodeHash x) = Just x
--
decodeHash :: ByteString -> Maybe ContentHash
-- | File path appropriate encoding of a hash
hashToPath :: ContentHash -> Path Rel Dir
-- | Inverse of hashToPath if given a valid input.
--
--
-- pathToHash (hashToPath x) = Just x
--
pathToHash :: FilePath -> Maybe ContentHash
-- | SHA256 cryptographic hash algorithm
data SHA256
-- | Represent a context for a given hash algorithm.
data Context a
-- | Represent a digest for a given hash algorithm.
--
-- This type is an instance of ByteArrayAccess from package
-- memory. Module Data.ByteArray provides many primitives
-- to work with those values including conversion to other types.
--
-- Creating a digest from a bytearray is also possible with function
-- digestFromByteString.
data Digest a
instance GHC.Show.Show Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance GHC.Generics.Generic Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance GHC.Show.Show Control.Funflow.ContentHashable.ExternallyAssuredFile
instance GHC.Generics.Generic Control.Funflow.ContentHashable.ExternallyAssuredFile
instance GHC.Generics.Generic Control.Funflow.ContentHashable.ContentHash
instance GHC.Classes.Ord Control.Funflow.ContentHashable.ContentHash
instance GHC.Classes.Eq Control.Funflow.ContentHashable.ContentHash
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance Data.Store.Impl.Store Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.ContentHashable.ExternallyAssuredDirectory
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.ContentHashable.ExternallyAssuredFile
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.ContentHashable.ExternallyAssuredFile
instance Data.Store.Impl.Store Control.Funflow.ContentHashable.ExternallyAssuredFile
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.ContentHashable.ExternallyAssuredFile
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.ContentHashable.DirectoryContent
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.ContentHashable.FileContent
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Fingerprint.Type.Fingerprint
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Bool
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Char
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Int
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Int.Int8
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Int.Int16
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Int.Int32
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Int.Int64
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Word
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Word.Word8
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Word.Word16
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Word.Word32
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Word.Word64
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Float
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Types.Double
instance (Control.Funflow.ContentHashable.ContentHashable m n, Data.Typeable.Internal.Typeable n) => Control.Funflow.ContentHashable.ContentHashable m (GHC.Real.Ratio n)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.Scientific.Scientific
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Integer.Type.Integer
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m GHC.Natural.Natural
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.ByteString.Internal.ByteString
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.ByteString.Lazy.Internal.ByteString
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.Text.Internal.Text
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.Text.Internal.Lazy.Text
instance (Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable v, Control.Funflow.ContentHashable.ContentHashable m k, Control.Funflow.ContentHashable.ContentHashable m v) => Control.Funflow.ContentHashable.ContentHashable m (Data.Map.Internal.Map k v)
instance (Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable v, Control.Funflow.ContentHashable.ContentHashable m k, Control.Funflow.ContentHashable.ContentHashable m v) => Control.Funflow.ContentHashable.ContentHashable m (Data.HashMap.Base.HashMap k v)
instance (Data.Typeable.Internal.Typeable v, Control.Funflow.ContentHashable.ContentHashable m v) => Control.Funflow.ContentHashable.ContentHashable m (Data.HashSet.HashSet v)
instance (Data.Typeable.Internal.Typeable a, Control.Funflow.ContentHashable.ContentHashable m a) => Control.Funflow.ContentHashable.ContentHashable m [a]
instance (Data.Typeable.Internal.Typeable a, Control.Funflow.ContentHashable.ContentHashable m a) => Control.Funflow.ContentHashable.ContentHashable m (GHC.Base.NonEmpty a)
instance (Data.Typeable.Internal.Typeable a, Control.Funflow.ContentHashable.ContentHashable m a) => Control.Funflow.ContentHashable.ContentHashable m (Data.Vector.Vector a)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m ()
instance (Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b) => Control.Funflow.ContentHashable.ContentHashable m (a, b)
instance (Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b, Control.Funflow.ContentHashable.ContentHashable m c) => Control.Funflow.ContentHashable.ContentHashable m (a, b, c)
instance (Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b, Control.Funflow.ContentHashable.ContentHashable m c, Control.Funflow.ContentHashable.ContentHashable m d) => Control.Funflow.ContentHashable.ContentHashable m (a, b, c, d)
instance (Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b, Control.Funflow.ContentHashable.ContentHashable m c, Control.Funflow.ContentHashable.ContentHashable m d, Control.Funflow.ContentHashable.ContentHashable m e) => Control.Funflow.ContentHashable.ContentHashable m (a, b, c, d, e)
instance (GHC.Base.Monad m, Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b, Control.Funflow.ContentHashable.ContentHashable m c, Control.Funflow.ContentHashable.ContentHashable m d, Control.Funflow.ContentHashable.ContentHashable m e, Control.Funflow.ContentHashable.ContentHashable m f) => Control.Funflow.ContentHashable.ContentHashable m (a, b, c, d, e, f)
instance (GHC.Base.Monad m, Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b, Control.Funflow.ContentHashable.ContentHashable m c, Control.Funflow.ContentHashable.ContentHashable m d, Control.Funflow.ContentHashable.ContentHashable m e, Control.Funflow.ContentHashable.ContentHashable m f, Control.Funflow.ContentHashable.ContentHashable m g) => Control.Funflow.ContentHashable.ContentHashable m (a, b, c, d, e, f, g)
instance Control.Funflow.ContentHashable.ContentHashable m a => Control.Funflow.ContentHashable.ContentHashable m (GHC.Base.Maybe a)
instance (Control.Funflow.ContentHashable.ContentHashable m a, Control.Funflow.ContentHashable.ContentHashable m b) => Control.Funflow.ContentHashable.ContentHashable m (Data.Either.Either a b)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.Aeson.Types.Internal.Value
instance Control.Funflow.ContentHashable.ContentHashable m c => Control.Funflow.ContentHashable.GContentHashable m (GHC.Generics.K1 i c)
instance (GHC.Base.Monad m, Data.Typeable.Internal.Typeable b, Data.Typeable.Internal.Typeable t) => Control.Funflow.ContentHashable.ContentHashable m (Path.Internal.Path b t)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Data.Time.Clock.Internal.UTCTime.UTCTime
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.GContentHashable m GHC.Generics.V1
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.GContentHashable m GHC.Generics.U1
instance (GHC.Generics.Constructor c, Control.Funflow.ContentHashable.GContentHashable m f) => Control.Funflow.ContentHashable.GContentHashable m (GHC.Generics.C1 c f)
instance (GHC.Generics.Datatype d, Control.Funflow.ContentHashable.GContentHashable m f) => Control.Funflow.ContentHashable.GContentHashable m (GHC.Generics.D1 d f)
instance Control.Funflow.ContentHashable.GContentHashable m f => Control.Funflow.ContentHashable.GContentHashable m (GHC.Generics.S1 s f)
instance (Control.Funflow.ContentHashable.GContentHashable m a, Control.Funflow.ContentHashable.GContentHashable m b) => Control.Funflow.ContentHashable.GContentHashable m (a GHC.Generics.:*: b)
instance (Control.Funflow.ContentHashable.GContentHashable m a, Control.Funflow.ContentHashable.GContentHashable m b) => Control.Funflow.ContentHashable.GContentHashable m (a GHC.Generics.:+: b)
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.ContentHashable.ContentHash
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.ContentHashable.ContentHash
instance Data.Hashable.Class.Hashable Control.Funflow.ContentHashable.ContentHash
instance GHC.Show.Show Control.Funflow.ContentHashable.ContentHash
instance Data.Store.Impl.Store Control.Funflow.ContentHashable.ContentHash
instance Database.SQLite.Simple.FromField.FromField Control.Funflow.ContentHashable.ContentHash
instance Database.SQLite.Simple.ToField.ToField Control.Funflow.ContentHashable.ContentHash
-- | Hash addressed store in file system.
--
-- Associates a key (ContentHash) with an item in the store. An
-- item can either be Missing, Pending, or Complete.
-- The state is persisted in the file system.
--
-- Items are stored under a path derived from their hash. Therefore,
-- there can be no two copies of the same item in the store. If two keys
-- are associated with the same item, then there will be only one copy of
-- that item in the store.
--
-- The store is thread-safe and multi-process safe.
--
-- It is assumed that the user that the process is running under is the
-- owner of the store root, or has permission to create it if missing.
--
-- It is assumed that the store root and its immediate contents are not
-- modified externally. The contents of pending items may be modified
-- externally.
--
-- Implementation notes:
--
-- The hash of an item can only be determined once it is completed. If
-- that hash already exists in the store, then the new item is discarded.
--
-- Store state is persisted in the file-system:
--
--
-- - Pending items are stored writable under the path
-- pending-<key>.
-- - Complete items are stored read-only under the path
-- item-<hash>, with a link under
-- complete-<key> pointing to that directory.
--
module Control.Funflow.ContentStore
-- | Open the store under the given root and perform the given action.
-- Closes the store once the action is complete
--
-- See also: open
withStore :: (MonadIO m, MonadMask m) => Path Abs Dir -> (ContentStore -> m a) -> m a
-- | open root opens a store under the given root directory.
--
-- The root directory is created if necessary.
--
-- It is not safe to have multiple store objects refer to the same root
-- directory.
open :: Path Abs Dir -> IO ContentStore
-- | Free the resources associated with the given store object.
--
-- The store object may not be used afterwards.
close :: ContentStore -> IO ()
-- | List all elements in the store (pending keys, completed keys,
-- completed items).
listAll :: MonadIO m => ContentStore -> m ([ContentHash], [ContentHash], [Item])
-- | List all pending keys in the store.
listPending :: MonadIO m => ContentStore -> m [ContentHash]
-- | List all completed keys in the store.
listComplete :: MonadIO m => ContentStore -> m [ContentHash]
-- | List all completed items in the store.
listItems :: MonadIO m => ContentStore -> m [Item]
-- | Query the state of the item under the given key.
query :: MonadIO m => ContentStore -> ContentHash -> m (Status () () ())
-- | Check if there is no complete or pending item under the given key.
isMissing :: MonadIO m => ContentStore -> ContentHash -> m Bool
-- | Check if there is a pending item under the given key.
isPending :: MonadIO m => ContentStore -> ContentHash -> m Bool
-- | Check if there is a completed item under the given key.
isComplete :: MonadIO m => ContentStore -> ContentHash -> m Bool
-- | Query the state under the given key and return the item if completed.
-- Doesn't block if the item is pending.
lookup :: MonadIO m => ContentStore -> ContentHash -> m (Status () () Item)
-- | Query the state under the given key and return the item if completed.
-- Return an Async to await an update, if pending.
lookupOrWait :: MonadIO m => ContentStore -> ContentHash -> m (Status () (Async Update) Item)
-- | Query the state under the given key and return the item once
-- completed. Blocks if the item is pending. Returns Nothing if
-- the item is missing, or failed to be completed.
waitUntilComplete :: MonadIO m => ContentStore -> ContentHash -> m (Maybe Item)
-- | Atomically query the state under the given key and mark pending if
-- missing.
--
-- Returns Complete item if the item is complete. Returns
-- Pending async if the item is pending, where
-- async is an Async to await updates on. Returns
-- Missing buildDir if the item was missing, and is now
-- pending. It should be constructed in the given buildDir, and
-- then marked as complete using markComplete.
constructOrAsync :: MonadIO m => ContentStore -> ContentHash -> m (Status (Path Abs Dir) (Async Update) Item)
-- | Atomically query the state under the given key and mark pending if
-- missing. Wait for the item to be completed, if already pending. Throws
-- a FailedToConstruct error if construction fails.
--
-- Returns Complete item if the item is complete. Returns
-- Missing buildDir if the item was missing, and is now
-- pending. It should be constructed in the given buildDir, and
-- then marked as complete using markComplete.
constructOrWait :: MonadIO m => ContentStore -> ContentHash -> m (Status (Path Abs Dir) Void Item)
-- | Atomically query the state under the given key and mark pending if
-- missing.
constructIfMissing :: MonadIO m => ContentStore -> ContentHash -> m (Status (Path Abs Dir) () Item)
-- | Atomically query the state under the given key and mark pending if
-- missing. Execute the given function to construct the item, mark as
-- complete on success and remove on failure. Forcibly removes if an
-- uncaught exception occurs during item construction.
withConstructIfMissing :: (MonadIO m, MonadMask m) => ContentStore -> ContentHash -> (Path Abs Dir -> m (Either e a)) -> m (Status e () (Maybe a, Item))
-- | Mark a non-existent item as pending.
--
-- Creates the build directory and returns its path.
--
-- See also: constructIfMissing.
markPending :: MonadIO m => ContentStore -> ContentHash -> m (Path Abs Dir)
-- | Mark a pending item as complete.
markComplete :: MonadIO m => ContentStore -> ContentHash -> m Item
-- | Remove a pending item.
--
-- It is the callers responsibility to ensure that no other threads or
-- processes will attempt to access the item's contents afterwards.
removeFailed :: MonadIO m => ContentStore -> ContentHash -> m ()
-- | Remove a key association independent of the corresponding item state.
-- Do nothing if no item exists under the given key.
--
-- It is the callers responsibility to ensure that no other threads or
-- processes will attempt to access the contents afterwards.
--
-- Note, this will leave an orphan item behind if no other keys point to
-- it. There is no garbage collection mechanism in place at the moment.
removeForcibly :: MonadIO m => ContentStore -> ContentHash -> m ()
-- | Remove a completed item in the store. Do nothing if not completed.
--
-- It is the callers responsibility to ensure that no other threads or
-- processes will attempt to access the contents afterwards.
--
-- Note, this will leave keys pointing to that item dangling. There is no
-- garbage collection mechanism in place at the moment.
removeItemForcibly :: MonadIO m => ContentStore -> Item -> m ()
-- | Link the given alias to the given item. If the alias existed before it
-- is overwritten.
assignAlias :: MonadIO m => ContentStore -> Alias -> Item -> m ()
-- | Lookup an item under the given alias. Returns Nothing if the
-- alias does not exist.
lookupAlias :: MonadIO m => ContentStore -> Alias -> m (Maybe Item)
-- | Remove the given alias.
removeAlias :: MonadIO m => ContentStore -> Alias -> m ()
-- | List all aliases and the respective items.
listAliases :: MonadIO m => ContentStore -> m [(Alias, Item)]
-- | Get all hashes that resulted in the given item.
getBackReferences :: MonadIO m => ContentStore -> Item -> m [ContentHash]
-- | Define the input items to a subtree.
setInputs :: MonadIO m => ContentStore -> ContentHash -> [Item] -> m ()
-- | Get the input items to a subtree if any were defined.
getInputs :: MonadIO m => ContentStore -> ContentHash -> m [Item]
-- | Set a metadata entry on an item.
setMetadata :: (ToField k, ToField v, MonadIO m) => ContentStore -> ContentHash -> k -> v -> m ()
-- | Retrieve a metadata entry on an item, or Nothing if missing.
getMetadata :: (ToField k, FromField v, MonadIO m) => ContentStore -> ContentHash -> k -> m (Maybe v)
-- | Create and open a new metadata file on a pending item in write mode.
createMetadataFile :: MonadIO m => ContentStore -> ContentHash -> Path Rel File -> m (Path Abs File, Handle)
-- | Return the path to a metadata file if it exists.
getMetadataFile :: MonadIO m => ContentStore -> ContentHash -> Path Rel File -> m (Maybe (Path Abs File))
itemHash :: Item -> ContentHash
-- | The store path of a completed item.
itemPath :: ContentStore -> Item -> Path Abs Dir
-- | The scoped path to a content item within the store.
itemRelPath :: Item -> Path Rel Dir
-- | The absolute path to content within the store.
contentPath :: ContentStore -> Content t -> Path Abs t
-- | Store item containing the given content.
contentItem :: Content t -> Item
contentFilename :: Content File -> Path Rel File
-- | The root directory of the store.
root :: ContentStore -> Path Abs Dir
-- | A hash addressed store on the file system.
data ContentStore
-- | A completed item in the ContentStore.
data Item
-- | File or directory within a content store Item.
data Content t
[All] :: Item -> Content Dir
[:>] :: Item -> Path Rel t -> Content t
-- | Append to the path within a store item.
(^>) :: Content Dir -> Path Rel t -> Content t
infixl 4 ^>
newtype Alias
Alias :: Text -> Alias
[unAlias] :: Alias -> Text
-- | Status of an item in the store.
data Status missing pending complete
-- | The item does not exist, yet.
Missing :: missing -> Status missing pending complete
-- | The item is under construction and not ready for consumption.
Pending :: pending -> Status missing pending complete
-- | The item is complete and ready for consumption.
Complete :: complete -> Status missing pending complete
type Status_ = Status () () ()
-- | Update about the status of a pending item.
data Update
-- | The item is now completed and ready for consumption.
Completed :: Item -> Update
-- | Constructing the item failed.
Failed :: Update
-- | Errors that can occur when interacting with the store.
data StoreError
-- | An item is not under construction when it should be.
NotPending :: ContentHash -> StoreError
-- | An item is already under construction when it should be missing.
AlreadyPending :: ContentHash -> StoreError
-- | An item is already complete when it shouldn't be.
AlreadyComplete :: ContentHash -> StoreError
-- | The link under the given hash points to an invalid path.
CorruptedLink :: ContentHash -> FilePath -> StoreError
-- | A failure occurred while waiting for the item to be constructed.
FailedToConstruct :: ContentHash -> StoreError
-- | IncompatibleStoreVersion storeDir actual expected The given
-- store has a version number that is incompatible.
IncompatibleStoreVersion :: (Path Abs Dir) -> Int -> Int -> StoreError
-- | MalformedMetadataEntry hash key The metadata entry for the
-- give hash, key pair is malformed.
MalformedMetadataEntry :: ContentHash -> SQLData -> StoreError
instance Data.Store.Impl.Store Control.Funflow.ContentStore.Alias
instance Database.SQLite.Simple.ToField.ToField Control.Funflow.ContentStore.Alias
instance Database.SQLite.Simple.FromField.FromField Control.Funflow.ContentStore.Alias
instance GHC.Show.Show Control.Funflow.ContentStore.Alias
instance GHC.Classes.Ord Control.Funflow.ContentStore.Alias
instance GHC.Classes.Eq Control.Funflow.ContentStore.Alias
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.ContentStore.Alias
instance GHC.Show.Show Control.Funflow.ContentStore.Update
instance GHC.Classes.Eq Control.Funflow.ContentStore.Update
instance GHC.Generics.Generic Control.Funflow.ContentStore.Item
instance GHC.Show.Show Control.Funflow.ContentStore.Item
instance GHC.Classes.Ord Control.Funflow.ContentStore.Item
instance GHC.Classes.Eq Control.Funflow.ContentStore.Item
instance GHC.Show.Show Control.Funflow.ContentStore.StoreError
instance (GHC.Show.Show missing, GHC.Show.Show pending, GHC.Show.Show complete) => GHC.Show.Show (Control.Funflow.ContentStore.Status missing pending complete)
instance (GHC.Classes.Eq missing, GHC.Classes.Eq pending, GHC.Classes.Eq complete) => GHC.Classes.Eq (Control.Funflow.ContentStore.Status missing pending complete)
instance GHC.Classes.Eq (Control.Funflow.ContentStore.Content t)
instance GHC.Show.Show (Control.Funflow.ContentStore.Content t)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m (Control.Funflow.ContentStore.Content Path.Dir)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m (Control.Funflow.ContentStore.Content Path.File)
instance GHC.Base.Monad m => Control.Funflow.ContentHashable.ContentHashable m Control.Funflow.ContentStore.Item
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.ContentStore.Item
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.ContentStore.Item
instance Data.Hashable.Class.Hashable Control.Funflow.ContentStore.Item
instance Data.Store.Impl.Store Control.Funflow.ContentStore.Item
instance GHC.Exception.Exception Control.Funflow.ContentStore.StoreError
-- | Definition of external tasks
module Control.Funflow.External
-- | Set of items which may be treated as an input path to an external
-- task.
data InputPath
-- | An item in the content store.
IPItem :: Item -> InputPath
-- | An external file whose contents are considered assured by the external
-- system.
IPExternalFile :: ExternallyAssuredFile -> InputPath
-- | An external directory whose contents are considered assured by the
-- external system.
IPExternalDir :: ExternallyAssuredDirectory -> InputPath
-- | Component of a parameter
data ParamField
-- | Text component.
ParamText :: !Text -> ParamField
-- | Reference to a path to a content store item.
ParamPath :: !InputPath -> ParamField
-- | Reference to an environment variable.
ParamEnv :: !Text -> ParamField
-- | Reference to the effective user ID of the executor.
ParamUid :: ParamField
-- | Reference to the effective group ID of the executor.
ParamGid :: ParamField
-- | Reference to the output path in the content store.
ParamOut :: ParamField
-- | A parameter to an external task
--
-- The runtime values to external references, e.g. environment variables,
-- should not significantly influence the result of the external task. In
-- particular, the content hash will not depend on these runtime values.
newtype Param
Param :: [ParamField] -> Param
-- | Converter of path components.
data ConvParam f
ConvParam :: Item -> f (Path Abs Dir) -> Text -> f Text -> f CUid -> f CGid -> f (Path Abs Dir) -> ConvParam f
-- | Resolve a reference to a content store item.
[convPath] :: ConvParam f -> Item -> f (Path Abs Dir)
-- | Resolve an environment variable.
[convEnv] :: ConvParam f -> Text -> f Text
-- | Resolve the effective user ID.
[convUid] :: ConvParam f -> f CUid
-- | Resolve the effective group ID.
[convGid] :: ConvParam f -> f CGid
-- | Resolve the output path in the content store.
[convOut] :: ConvParam f -> f (Path Abs Dir)
paramFieldToText :: Applicative f => ConvParam f -> ParamField -> f Text
-- | Transform a parameter to text using the given converter.
paramToText :: Applicative f => ConvParam f -> Param -> f Text
stringParam :: String -> Param
textParam :: Text -> Param
-- | Reference to a path to either: - a content store item, or - an
-- externally assured file/directory.
pathParam :: InputPath -> Param
-- | Reference to a path to a file or directory within a store item.
contentParam :: Content t -> Param
-- | Reference an externally assured file
externalFileParam :: ExternallyAssuredFile -> Param
-- | Reference an externally assured file
externalDirectoryParam :: ExternallyAssuredDirectory -> Param
-- | Reference to an environment variable.
envParam :: Text -> Param
-- | Reference to the effective user ID of the executor.
uidParam :: Param
-- | Reference to the effective group ID of the executor.
gidParam :: Param
-- | Reference to the output path in the content store.
outParam :: Param
-- | Control how and where stdout from the process is captured. Some
-- external steps will write their output to stdout rather than to a
-- file.
data OutputCapture
-- | Specify that the step will write its output files directly, and that
-- stdout will not be captured in the step output.
NoOutputCapture :: OutputCapture
-- | Capture output to a file named out in the output directory.
StdOutCapture :: OutputCapture
-- | Capture output to a custom named file in the output directory.
CustomOutCapture :: (Path Rel File) -> OutputCapture
-- | Get the file to write output to, if this is desired.
outputCaptureToRelFile :: OutputCapture -> Maybe (Path Rel File)
-- | A monomorphic description of an external task. This is basically just
-- a command which can be run.
data ExternalTask
ExternalTask :: Text -> [Param] -> [(Text, Param)] -> OutputCapture -> ExternalTask
[_etCommand] :: ExternalTask -> Text
-- | Environment variables to set for the scope of the execution.
[_etParams] :: ExternalTask -> [Param]
[_etEnv] :: ExternalTask -> [(Text, Param)]
[_etWriteToStdOut] :: ExternalTask -> OutputCapture
data TaskDescription
TaskDescription :: ContentHash -> ExternalTask -> TaskDescription
[_tdOutput] :: TaskDescription -> ContentHash
[_tdTask] :: TaskDescription -> ExternalTask
etWriteToStdOut :: Lens' ExternalTask OutputCapture
etParams :: Lens' ExternalTask [Param]
etEnv :: Lens' ExternalTask [(Text, Param)]
etCommand :: Lens' ExternalTask Text
tdTask :: Lens' TaskDescription ExternalTask
tdOutput :: Lens' TaskDescription ContentHash
instance GHC.Show.Show Control.Funflow.External.TaskDescription
instance GHC.Generics.Generic Control.Funflow.External.TaskDescription
instance GHC.Show.Show Control.Funflow.External.ExternalTask
instance GHC.Generics.Generic Control.Funflow.External.ExternalTask
instance GHC.Show.Show Control.Funflow.External.OutputCapture
instance GHC.Generics.Generic Control.Funflow.External.OutputCapture
instance GHC.Show.Show Control.Funflow.External.Param
instance GHC.Base.Semigroup Control.Funflow.External.Param
instance GHC.Base.Monoid Control.Funflow.External.Param
instance GHC.Generics.Generic Control.Funflow.External.Param
instance GHC.Show.Show Control.Funflow.External.ParamField
instance GHC.Generics.Generic Control.Funflow.External.ParamField
instance GHC.Show.Show Control.Funflow.External.InputPath
instance GHC.Generics.Generic Control.Funflow.External.InputPath
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.ExternalTask
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.External.ExternalTask
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.External.ExternalTask
instance Data.Store.Impl.Store Control.Funflow.External.ExternalTask
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.OutputCapture
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.External.OutputCapture
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.External.OutputCapture
instance Data.Store.Impl.Store Control.Funflow.External.OutputCapture
instance Data.String.IsString Control.Funflow.External.Param
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.Param
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.External.Param
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.External.Param
instance Data.Store.Impl.Store Control.Funflow.External.Param
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.ParamField
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.External.ParamField
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.External.ParamField
instance Data.Store.Impl.Store Control.Funflow.External.ParamField
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.InputPath
instance Data.Aeson.Types.FromJSON.FromJSON Control.Funflow.External.InputPath
instance Data.Aeson.Types.ToJSON.ToJSON Control.Funflow.External.InputPath
instance Data.Store.Impl.Store Control.Funflow.External.InputPath
-- | Module supporting the use of docker containers as external tasks.
--
-- In general, an external task can be any command. This module just
-- makes it easier to specify certain tasks which will run inside docker
-- containers. It handles constructing the call to docker, mounting input
-- and output directories, and specifying the docker image and version to
-- use.
module Control.Funflow.External.Docker
data Config
Config :: Text -> Maybe Text -> Param -> [Param] -> [(Text, Param)] -> OutputCapture -> Config
[image] :: Config -> Text
[optImageID] :: Config -> Maybe Text
[command] :: Config -> Param
[args] :: Config -> [Param]
[env] :: Config -> [(Text, Param)]
[stdout] :: Config -> OutputCapture
toExternal :: Config -> ExternalTask
instance GHC.Generics.Generic Control.Funflow.External.Docker.Docker
instance GHC.Generics.Generic Control.Funflow.External.Docker.Config
instance GHC.Generics.Generic Control.Funflow.External.Docker.Bind
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.Docker.Docker
instance Control.Funflow.ContentHashable.ContentHashable GHC.Types.IO Control.Funflow.External.Docker.Bind
instance GHC.Base.Semigroup Control.Funflow.External.Docker.Bind
instance GHC.Base.Monoid Control.Funflow.External.Docker.Bind
-- | A Funflow coordinator is used to distribute tasks amongst multiple
-- executors. It provides a functionality to submit tasks, to fetch them
-- for execution, and to check on their status.
--
-- There are multiple possible instantiations of the Coordinator
-- class.
module Control.Funflow.External.Coordinator
-- | Information about an executor capable of running tasks. Currently this
-- is just a newtype wrapper around hostname.
newtype Executor
Executor :: HostName -> Executor
data TaskStatus
-- | Task is in the queue and has not begun executing
Pending :: TaskStatus
Running :: ExecutionInfo -> TaskStatus
Completed :: ExecutionInfo -> TaskStatus
-- | Task has failed with failure count
Failed :: ExecutionInfo -> Int -> TaskStatus
data TaskInfo
KnownTask :: TaskStatus -> TaskInfo
UnknownTask :: TaskInfo
data ExecutionInfo
ExecutionInfo :: Executor -> TimeSpec -> ExecutionInfo
[_eiExecutor] :: ExecutionInfo -> Executor
[_eiElapsed] :: ExecutionInfo -> TimeSpec
data TaskError
ExternalTaskFailed :: TaskDescription -> TaskInfo -> (Maybe (Path Abs File)) -> (Maybe (Path Abs File)) -> TaskError
class Coordinator c where {
type family Config c;
type family Hook c = h | h -> c;
}
-- | Perform any necessary initialisation to connect to the coordinator.
initialise :: (Coordinator c, MonadIO m) => Config c -> m (Hook c)
-- | Submit a task to the task queue. It is allowed to overwrite a known
-- task.
submitTask :: (Coordinator c, MonadIO m) => Hook c -> TaskDescription -> m ()
-- | View the size of the current task queue
queueSize :: (Coordinator c, MonadIO m) => Hook c -> m Int
-- | Fetch information on the current task
taskInfo :: (Coordinator c, MonadIO m) => Hook c -> ContentHash -> m TaskInfo
-- | Pop a task off of the queue for execution. The popped task should be
-- added to the execution queue
popTask :: (Coordinator c, MonadIO m) => Hook c -> Executor -> m (Maybe TaskDescription)
-- | Await task completion.
--
-- If the task is complete, this will return 'KnownTask Completed'. If
-- the task is failed, this will return 'KnownTask Failed'. If the task
-- is not known to the system, this will return UnknownTask.
-- Otherwise (if the task is pending or running), this will block until
-- the task either completes or fails.
awaitTask :: (Coordinator c, MonadIO m) => Hook c -> ContentHash -> m TaskInfo
-- | Update execution status for a running task. This should error for a
-- task which is not running.
updateTaskStatus :: (Coordinator c, MonadIO m) => Hook c -> ContentHash -> TaskStatus -> m ()
-- | Remove all pending tasks from the queue.
dropTasks :: (Coordinator c, MonadIO m) => Hook c -> m ()
eiExecutor :: Lens' ExecutionInfo Executor
eiElapsed :: Lens' ExecutionInfo TimeSpec
startTask :: (Coordinator c, MonadIO m) => Hook c -> m (Maybe TaskDescription)
-- | Check if a task is currently 'in progress' - e.g. pending or running.
isInProgress :: (Coordinator c, MonadIO m) => Hook c -> ContentHash -> m Bool
-- | Pop a task off of the queue for execution. Passes the popped task to
-- the given function for execution. If the function returns success
-- (Right), then the task will be marked as completed in the given
-- time. If the function returns failure (Left), then the task
-- will be marked as failed. If the function raises an exception or is
-- interrupted by an asynchronous exception, then the task will be placed
-- back on the task queue and the exception propagated. Returns
-- Nothing if no task is available and Just () on
-- task completion or regular failure.
withPopTask :: (Coordinator c, MonadIO m, MonadMask m, KatipContext m) => Hook c -> Executor -> (TaskDescription -> m (TimeSpec, Either Int ())) -> m (Maybe ())
instance Data.Store.Impl.Store Control.Funflow.External.Coordinator.TaskInfo
instance Data.Store.Impl.Store Control.Funflow.External.Coordinator.ExecutionInfo
instance Data.Store.Impl.Store Control.Funflow.External.Coordinator.TaskStatus
instance GHC.Show.Show Control.Funflow.External.Coordinator.TaskError
instance GHC.Show.Show Control.Funflow.External.Coordinator.TaskInfo
instance GHC.Show.Show Control.Funflow.External.Coordinator.TaskStatus
instance GHC.Show.Show Control.Funflow.External.Coordinator.ExecutionInfo
instance Data.Store.Impl.Store Control.Funflow.External.Coordinator.Executor
instance GHC.Show.Show Control.Funflow.External.Coordinator.Executor
instance GHC.Exception.Exception Control.Funflow.External.Coordinator.TaskError
-- | Executor for external tasks.
--
-- An executor will poll for tasks on the co-ordinator, mark them as in
-- progress and then execute them.
--
-- You probably want to start with executeLoop.
module Control.Funflow.External.Executor
data ExecutionResult
-- | The result already exists in the store and there is no need to
-- execute. This is also returned if the job is already running
-- elsewhere.
Cached :: ExecutionResult
-- | The computation is already running elsewhere. This is probably
-- indicative of a bug, because the coordinator should only allow one
-- instance of a task to be running at any time.
AlreadyRunning :: ExecutionResult
-- | Execution completed successfully after a certain amount of time.
Success :: TimeSpec -> ExecutionResult
-- | Execution failed with the following exit code. TODO where should logs
-- go?
Failure :: TimeSpec -> Int -> ExecutionResult
-- | The executor itself failed to execute the external task. E.g. because
-- the executable was not found.
ExecutorFailure :: IOException -> ExecutionResult
-- | Execute an individual task.
execute :: ContentStore -> TaskDescription -> KatipContextT IO ExecutionResult
-- | Execute tasks forever
executeLoop :: forall c. Coordinator c => c -> Config c -> ContentStore -> IO ()
-- | Same as executeLoop, but allows specifying a custom
-- Scribe for logging
executeLoopWithScribe :: forall c. Coordinator c => c -> Config c -> ContentStore -> Scribe -> IO ()
-- | withFollowFile in out follows the file in and prints
-- contents to out as they appear. The file must exist. Doesn't
-- handle file truncation.
withFollowFile :: Path Abs File -> Handle -> IO a -> IO a
-- | SQLLite co-ordinator for Funflow.
--
-- This co-ordinator effectively uses the shared filesystem as a tool for
-- task distribution and sequencing. This means that it can control a
-- distributed funflow task without needing any additional processes
-- running.
module Control.Funflow.External.Coordinator.SQLite
-- | SQLite coordinator tag.
data SQLite
SQLite :: SQLite
instance GHC.Show.Show Control.Funflow.External.Coordinator.SQLite.SQLiteCoordinatorError
instance Database.SQLite.Simple.FromField.FromField Control.Funflow.External.Coordinator.SQLite.SqlExternal
instance GHC.Exception.Exception Control.Funflow.External.Coordinator.SQLite.SQLiteCoordinatorError
instance Control.Funflow.External.Coordinator.Coordinator Control.Funflow.External.Coordinator.SQLite.SQLite
instance Database.SQLite.Simple.FromRow.FromRow Control.Funflow.External.Coordinator.SQLite.SqlTask
instance Database.SQLite.Simple.ToField.ToField Control.Funflow.External.Coordinator.SQLite.SqlExternal
instance Database.SQLite.Simple.FromRow.FromRow Control.Funflow.External.Coordinator.SQLite.SqlTaskInfo
instance GHC.Enum.Enum Control.Funflow.External.Coordinator.SQLite.SqlTaskStatus
instance Database.SQLite.Simple.FromField.FromField Control.Funflow.External.Coordinator.SQLite.SqlExecutor
instance Database.SQLite.Simple.ToField.ToField Control.Funflow.External.Coordinator.SQLite.SqlExecutor
instance Database.SQLite.Simple.FromField.FromField Control.Funflow.External.Coordinator.SQLite.SqlTaskStatus
instance Database.SQLite.Simple.ToField.ToField Control.Funflow.External.Coordinator.SQLite.SqlTaskStatus
-- | Redis-based co-ordinator for Funflow.
--
-- There are two co-ordinators defined in this module. They differ in
-- whether they open a new connection to Redis or re-use an existing one.
-- Other than that they behave identically.
module Control.Funflow.External.Coordinator.Redis
data Redis
Redis :: Redis
data RedisPreconnected
RedisPreconnected :: RedisPreconnected
instance Control.Funflow.External.Coordinator.Coordinator Control.Funflow.External.Coordinator.Redis.RedisPreconnected
instance Control.Funflow.External.Coordinator.Coordinator Control.Funflow.External.Coordinator.Redis.Redis
-- | In-memory co-ordinator for funflow. This module is not greatly useful
-- except for testing purposes.
module Control.Funflow.External.Coordinator.Memory
data MemoryCoordinator
MemoryCoordinator :: MemoryCoordinator
data MemHook
MemHook :: TVar [TaskDescription] -> TVar (Map ContentHash TaskStatus) -> MemHook
[_mhTaskQueue] :: MemHook -> TVar [TaskDescription]
[_mhExecutionQueue] :: MemHook -> TVar (Map ContentHash TaskStatus)
mhTaskQueue :: Lens' MemHook (TVar [TaskDescription])
mhExecutionQueue :: Lens' MemHook (TVar (Map ContentHash TaskStatus))
createMemoryCoordinator :: IO MemHook
instance Control.Funflow.External.Coordinator.Coordinator Control.Funflow.External.Coordinator.Memory.MemoryCoordinator
-- | This module contains the means to execute a pipeline.
--
-- You should probably start with withSimpleLocalRunner and
-- runSimpleFlow. The other functions in this module provide more
-- flexible versions of runSimpleFlow.
module Control.Funflow.Exec.Simple
-- | Run a flow, discarding all logging.
runFlow :: forall c eff ex a b. (Coordinator c, Exception ex) => c -> Config c -> ContentStore -> (eff ~> AsyncA IO) -> Int -> Flow eff ex a b -> a -> IO (Either ex b)
-- | Simple evaulation of a flow
runFlowEx :: forall c eff ex a b. (Coordinator c, Exception ex) => c -> Config c -> ContentStore -> (eff ~> AsyncA (KatipContextT IO)) -> Int -> Flow eff ex a b -> a -> KatipContextT IO b
-- | Run a simple flow. Logging will be sent to stderr
runSimpleFlow :: forall c a b. (Coordinator c) => c -> Config c -> ContentStore -> SimpleFlow a b -> a -> IO (Either SomeException b)
-- | Create a full pipeline runner locally. This includes an executor for
-- executing external tasks. This function is specialised to
-- SimpleFlow since in cases where a custom term algebra is in
-- use, we assume that probably a centralised coordinator and external
-- runners may be desired as well.
withSimpleLocalRunner :: Path Abs Dir -> ((SimpleFlow a b -> a -> IO (Either SomeException b)) -> IO c) -> IO c
-- | Template Haskell splices for the funflow cache.
module Control.Funflow.Cache.TH
-- | Create a default cacher with a random identity.
--
-- Note that this cacher is deliberately conservative - e.g. if the
-- application is recompiled, the cache will not be reused.
defaultCacher :: Q Exp
-- | Create a default cacher based on the location of this splice. Note
-- that this may lead to invalid cacheing if the code is changed without
-- the version being updated.
defaultCacherLoc :: Int -> Q Exp
instance Data.Hashable.Class.Hashable Language.Haskell.TH.Syntax.Loc
-- | Pretty-printer for Funflow diagrams.
module Control.Funflow.Pretty
ppFlow :: Flow eff ex a b -> Doc
showFlow :: Flow eff ex a b -> String
-- | Miscallaneous steps to form part of Funflow computations.
module Control.Funflow.Steps
-- | `retry n s f` reruns f on failure at most n times with a
-- delay of s seconds between retries
retry :: forall arr eff ex a b. (Exception ex, Store a, ArrowFlow eff ex arr) => Int -> Int -> arr a b -> arr a b
assignAliasInStore :: ArrowFlow eff ex arr => arr (Alias, Item) ()
-- | copyDirToStore (dIn, Nothing) copies the contents of
-- dIn into the store right under the subtree.
--
-- | copyDirToStore (dIn, Just dOut) copies the contents of
-- dIn into the store under relative path dOut within
-- the subtree
copyDirToStore :: ArrowFlow eff ex arr => arr (DirectoryContent, Maybe (Path Rel Dir)) (Content Dir)
-- | copyFileToStore (fIn, fOut) copies the contents of
-- fIn into the store under the relative path fOut
-- within the subtree.
copyFileToStore :: ArrowFlow eff ex arr => arr (FileContent, Path Rel File) (Content File)
-- | List the contents of a directory within the store
listDirContents :: ArrowFlow eff ex arr => arr (Content Dir) ([Content Dir], [Content File])
-- | Search for files in the directory matching the given text string, as a
-- glob pattern.
globDir :: ArrowFlow eff ex arr => arr (Content Dir, String) [Content File]
-- | Search for files in the directory matching the given pattern.
globDirPattern :: ArrowFlow eff ex arr => arr (Content Dir, Pattern) [Content File]
lookupAliasInStore :: ArrowFlow eff ex arr => arr Alias (Maybe Item)
-- | Merge a number of store directories together into a single output
-- directory. This uses hardlinks to avoid duplicating the data on disk.
mergeDirs :: ArrowFlow eff ex arr => arr [Content Dir] (Content Dir)
-- | Merge a number of files into a single output directory.
mergeFiles :: ArrowFlow eff ex arr => arr [Content File] (Content Dir)
putInStoreAt :: (ContentHashable IO a, Typeable t, ArrowFlow eff ex arr) => (Path Abs t -> a -> IO ()) -> arr (a, Path Rel t) (Content t)
-- | Read the contents of the given file in the store.
readString :: ArrowFlow eff ex arr => arr (Content File) String
-- | Read the contents of a file named out within the given item.
readString_ :: ArrowFlow eff ex arr => arr Item String
-- | Read a YAML file from the given file in the store.
readYaml :: FromJSON a => SimpleFlow (Content File) (Either ParseException a)
writeExecutableString :: ArrowFlow eff ex arr => arr (String, Path Rel File) (Content File)
-- | Create and write into a file under the given path in the store.
writeString :: ArrowFlow eff ex arr => arr (String, Path Rel File) (Content File)
-- | Create and write into a file named out within the given item.
writeString_ :: ArrowFlow eff ex arr => arr String (Content File)
-- | Write a YAML file under the given name to the store.
writeYaml :: (ContentHashable IO a, ToJSON a) => SimpleFlow (a, Path Rel File) (Content File)
-- | Write a YAML file named out.yaml to the store.
writeYaml_ :: (ContentHashable IO a, ToJSON a) => SimpleFlow a (Content File)
docker :: (ContentHashable IO a, ArrowFlow eff ex arr) => (a -> Config) -> arr a Item
promptFor :: (Read a, ArrowFlow eff ex arr) => arr String a
printS :: (Show a, ArrowFlow eff ex arr) => arr a ()
failStep :: ArrowFlow eff ex arr => arr () ()
worstBernoulli :: (Exception ex, ArrowFlow eff ex arr) => (String -> ex) -> arr Double Double
-- | pause for a given number of seconds. Thread through a value to ensure
-- delay does not happen inparallel with other processing
pauseWith :: (Store a, ArrowFlow eff ex arr) => arr (Int, a) a
-- | on first invocation die and leave a suicide note on second invocation
-- it is resurrected and destroys suicide note, returning contents
melancholicLazarus :: ArrowFlow eff ex arr => arr String String
-- | Central Funflow module.
--
-- This module just re-exports various other modules for convenience.
module Control.Funflow
type Flow eff ex = ErrorChoice ex (Flow' eff)
type SimpleFlow = Flow NoEffect SomeException
type ==> = SimpleFlow
data NoEffect a b
data Flow' eff a b
[Step] :: Properties a b -> (a -> b) -> Flow' eff a b
[StepIO] :: Properties a b -> (a -> IO b) -> Flow' eff a b
[External] :: ExternalProperties a -> (a -> ExternalTask) -> Flow' eff a Item
[PutInStore] :: ContentHashable IO a => (Path Abs Dir -> a -> IO ()) -> Flow' eff a Item
[GetFromStore] :: (Path Abs t -> IO a) -> Flow' eff (Content t) a
[InternalManipulateStore] :: (ContentStore -> a -> IO b) -> Flow' eff a b
[Wrapped] :: Properties a b -> eff a b -> Flow' eff a b
-- | A cacher is responsible for controlling how steps are cached.
data Cacher i o
-- | This step cannot be cached (default).
NoCache :: Cacher i o
Cache :: Int -> i -> ContentHash -> o -> ByteString -> ByteString -> o -> Cacher i o
-- | Function to encode the input into a content hash. This function
-- additionally takes an identities which gets incorporated into
-- the cacher.
[cacherKey] :: Cacher i o -> Int -> i -> ContentHash
[cacherStoreValue] :: Cacher i o -> o -> ByteString
-- | Attempt to read the cache value back. May throw exceptions.
[cacherReadValue] :: Cacher i o -> ByteString -> o
-- | Additional properties associated with external tasks.
data ExternalProperties a
ExternalProperties :: MDWriter a () -> Bool -> ExternalProperties a
-- | Write additional metadata to the content store.
[ep_mdpolicy] :: ExternalProperties a -> MDWriter a ()
-- | Specify that this external step is impure, and as such should not be
-- cached.
[ep_impure] :: ExternalProperties a -> Bool
-- | Metadata writer
type MDWriter i o = Maybe (i -> o -> [(Text, ByteString)])
data Properties i o
Properties :: Maybe Text -> Cacher i o -> MDWriter i o -> Properties i o
-- | Name of this step. Used when describing the step in diagrams or other
-- reporting.
[name] :: Properties i o -> Maybe Text
-- | Specify whether this step can be cached or not and, if so, how to do
-- so.
[cache] :: Properties i o -> Cacher i o
-- | Write additional metadata to the content store.
[mdpolicy] :: Properties i o -> MDWriter i o
defaultCacherWithIdent :: (Store o, ContentHashable Identity i) => Int -> Cacher i o
-- | Create a default cacher with a random identity.
--
-- Note that this cacher is deliberately conservative - e.g. if the
-- application is recompiled, the cache will not be reused.
defaultCacher :: Q Exp
-- | Create a default cacher based on the location of this splice. Note
-- that this may lead to invalid cacheing if the code is changed without
-- the version being updated.
defaultCacherLoc :: Int -> Q Exp
class (ArrowChoice arr, ArrowError ex arr) => ArrowFlow eff ex arr | arr -> eff ex
-- | Create a flow from a pure function.
step' :: ArrowFlow eff ex arr => Properties a b -> (a -> b) -> arr a b
-- | Create a flow from an IO action.
stepIO' :: ArrowFlow eff ex arr => Properties a b -> (a -> IO b) -> arr a b
-- | Create an external task in the flow.
external :: ArrowFlow eff ex arr => (a -> ExternalTask) -> arr a Item
-- | Create an external task with additional properties
external' :: ArrowFlow eff ex arr => ExternalProperties a -> (a -> ExternalTask) -> arr a Item
-- | Create a flow from a user-defined effect.
wrap' :: ArrowFlow eff ex arr => Properties a b -> eff a b -> arr a b
-- | Create a flow which will write its incoming data to the store.
putInStore :: (ArrowFlow eff ex arr, ContentHashable IO a) => (Path Abs Dir -> a -> IO ()) -> arr a Item
-- | Create a flow which will read data from the given store item.
getFromStore :: ArrowFlow eff ex arr => (Path Abs t -> IO a) -> arr (Content t) a
-- | Perform some internal manipulation of the content store.
internalManipulateStore :: ArrowFlow eff ex arr => (ContentStore -> a -> IO b) -> arr a b
-- | Create a flow from a pure function. This is a variant on step'
-- which uses the default properties.
step :: ArrowFlow eff ex arr => (a -> b) -> arr a b
-- | Create a flow from an IO action. This is a variant on stepIO'
-- which uses the default properties.
stepIO :: ArrowFlow eff ex arr => (a -> IO b) -> arr a b
wrap :: ArrowFlow eff ex arr => eff a b -> arr a b
-- | Open the store under the given root and perform the given action.
-- Closes the store once the action is complete
--
-- See also: open
withStore :: (MonadIO m, MonadMask m) => Path Abs Dir -> (ContentStore -> m a) -> m a