haxl-2.1.2.0: A Haskell library for efficient, concurrent, and concise data access.

Safe HaskellNone
LanguageHaskell2010

Haxl.Core.Monad

Contents

Description

The implementation of the Haxl monad. Most users should import Haxl.Core instead of importing this module directly.

Synopsis

The monad

newtype GenHaxl u w a Source #

The Haxl monad, which does several things:

  • It is a reader monad for Env, which contains the current state of the scheduler, including unfetched requests and the run queue of computations.
  • It is a writer monad for WriteTree. We strongly advise these be used only for logs used for debugging. These are not memoized. Other relevant writes should be returned as function output, which is the more "functional" way.

Constructors

GenHaxl 

Fields

Instances
Monad (GenHaxl u w) Source # 
Instance details

Defined in Haxl.Core.Monad

Methods

(>>=) :: GenHaxl u w a -> (a -> GenHaxl u w b) -> GenHaxl u w b #

(>>) :: GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w b #

return :: a -> GenHaxl u w a #

fail :: String -> GenHaxl u w a #

Functor (GenHaxl u w) Source # 
Instance details

Defined in Haxl.Core.Monad

Methods

fmap :: (a -> b) -> GenHaxl u w a -> GenHaxl u w b #

(<$) :: a -> GenHaxl u w b -> GenHaxl u w a #

Applicative (GenHaxl u w) Source # 
Instance details

Defined in Haxl.Core.Monad

Methods

pure :: a -> GenHaxl u w a #

(<*>) :: GenHaxl u w (a -> b) -> GenHaxl u w a -> GenHaxl u w b #

liftA2 :: (a -> b -> c) -> GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w c #

(*>) :: GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w b #

(<*) :: GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w a #

MonadThrow (GenHaxl u w) Source #

Since: 0.3.1.0

Instance details

Defined in Haxl.Core.Monad

Methods

throwM :: Exception e => e -> GenHaxl u w a #

MonadCatch (GenHaxl u w) Source #

Since: 0.3.1.0

Instance details

Defined in Haxl.Core.Monad

Methods

catch :: Exception e => GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a #

Fractional a => Fractional (GenHaxl u w a) Source # 
Instance details

Defined in Haxl.Prelude

Methods

(/) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a #

recip :: GenHaxl u w a -> GenHaxl u w a #

fromRational :: Rational -> GenHaxl u w a #

Num a => Num (GenHaxl u w a) Source # 
Instance details

Defined in Haxl.Prelude

Methods

(+) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a #

(-) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a #

(*) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a #

negate :: GenHaxl u w a -> GenHaxl u w a #

abs :: GenHaxl u w a -> GenHaxl u w a #

signum :: GenHaxl u w a -> GenHaxl u w a #

fromInteger :: Integer -> GenHaxl u w a #

IsString a => IsString (GenHaxl u w a) Source # 
Instance details

Defined in Haxl.Core.Monad

Methods

fromString :: String -> GenHaxl u w a #

u1 ~ u2 => IfThenElse (GenHaxl u1 w Bool) (GenHaxl u2 w a) Source # 
Instance details

Defined in Haxl.Prelude

Methods

ifThenElse :: GenHaxl u1 w Bool -> GenHaxl u2 w a -> GenHaxl u2 w a -> GenHaxl u2 w a Source #

data Result u w a Source #

The result of a computation is either Done with a value, Throw with an exception, or Blocked on the result of a data fetch with a continuation.

Constructors

Done a 
Throw SomeException 
Blocked !(IVar u w b) (Cont u w a)

The IVar is what we are blocked on; Cont is the continuation. This might be wrapped further if we're nested inside multiple >>=, before finally being added to the IVar. Morally b -> GenHaxl u w a, but see IVar,

Instances
Show a => Show (Result u w a) Source # 
Instance details

Defined in Haxl.Core.Monad

Methods

showsPrec :: Int -> Result u w a -> ShowS #

show :: Result u w a -> String #

showList :: [Result u w a] -> ShowS #

Writes (for debugging only)

data WriteTree w Source #

A tree of writes done during a Haxl computation. We could use a simple list, but this allows us to avoid multiple mappends when concatenating writes from two haxl computations.

Users should try to treat this data type as opaque, and prefer to use flattenWT to get a simple list of writes from a WriteTree.

Instances
Show w => Show (WriteTree w) Source # 
Instance details

Defined in Haxl.Core.Monad

tellWrite :: w -> GenHaxl u w () Source #

write :: WriteTree w -> GenHaxl u w () Source #

Cont

data Cont u w a Source #

A data representation of a Haxl continuation. This is to avoid repeatedly traversing a left-biased tree in a continuation, leading O(n^2) complexity for some pathalogical cases - see the "seql" benchmark in tests/MonadBench.hs. See "A Smart View on Datatypes", Jaskelioff/Rivas, ICFP'15

Constructors

Cont (GenHaxl u w a) 
(Cont u w b) :>>= (b -> GenHaxl u w a) 
(b -> a) :<$> (Cont u w b) 

toHaxl :: Cont u w a -> GenHaxl u w a Source #

IVar

newtype IVar u w a Source #

A synchronisation point. It either contains a value, or a list of computations waiting for the value.

Constructors

IVar (IORef (IVarContents u w a)) 

data IVarContents u w a Source #

Constructors

IVarFull (ResultVal a w) 
IVarEmpty (JobList u w) 

newIVar :: IO (IVar u w a) Source #

newFullIVar :: ResultVal a w -> IO (IVar u w a) Source #

getIVar :: IVar u w a -> GenHaxl u w a Source #

putIVar :: IVar u w a -> ResultVal a w -> Env u w -> IO () Source #

ResultVal

data ResultVal a w Source #

The contents of a full IVar. We have to distinguish exceptions thrown in the IO monad from exceptions thrown in the Haxl monad, so that when the result is fetched using getIVar, we can throw the exception in the right way.

done :: ResultVal a w -> IO (Result u w a) Source #

CompleteReq

data CompleteReq u w Source #

A completed request from a data source, containing the result, and the IVar representing the blocked computations. The job of a data source is just to add these to a queue (completions) using putResult; the scheduler collects them from the queue and unblocks the relevant computations.

Constructors

CompleteReq (Either SomeException a) !(IVar u w a) !Int64 

Env

data Env u w Source #

The data we carry around in the Haxl monad.

Constructors

Env 

Fields

  • cacheRef :: !(IORef (DataCache (IVar u w)))

    cached data fetches

  • memoRef :: !(IORef (DataCache (IVar u w)))

    memoized computations

  • flags :: !Flags
     
  • userEnv :: u

    user-supplied data, retrievable with env

  • statsRef :: !(IORef Stats)

    statistics, collected according to the report level in flags.

  • profLabel :: ProfileLabel

    current profiling label, see withLabel

  • profRef :: !(IORef Profile)

    profiling data, collected according to the report level in flags.

  • states :: StateStore

    Data sources and other components can store their state in here. Items in this store must be instances of StateKey.

  • reqStoreRef :: !(IORef (RequestStore u))

    The set of requests that we have not submitted to data sources yet. Owned by the scheduler.

  • runQueueRef :: !(IORef (JobList u w))

    runnable computations. Things get added to here when we wake up a computation that was waiting for something. When the list is empty, either we're finished, or we're waiting for some data fetch to return.

  • submittedReqsRef :: !(IORef ReqCountMap)

    all outgone fetches which haven't yet returned. Entries are removed from this map as the fetches finish. This field is useful for tracking outgone fetches to detect downstream failures.

  • completions :: !(TVar [CompleteReq u w])

    Requests that have completed. Modified by data sources (via putResult) and the scheduler. Waiting for this list to become non-empty is how the scheduler blocks waiting for data fetches to return.

  • pendingWaits :: [IO ()]

    this is a list of IO actions returned by FutureFetch data sources. These do a blocking wait for the results of some data fetch.

  • speculative :: !Int
     
  • writeLogsRef :: !(IORef (WriteTree w))

    A log of all writes done as part of this haxl computation. Any haxl computation that needs to be memoized runs in its own environment so

type Caches u w = (IORef (DataCache (IVar u w)), IORef (DataCache (IVar u w))) Source #

caches :: Env u w -> Caches u w Source #

initEnvWithData :: StateStore -> u -> Caches u w -> IO (Env u w) Source #

Initialize an environment with a StateStore, an input map, a preexisting DataCache, and a seed for the random number generator.

initEnv :: StateStore -> u -> IO (Env u w) Source #

Initializes an environment with StateStore and an input map.

emptyEnv :: u -> IO (Env u w) Source #

A new, empty environment.

env :: (Env u w -> a) -> GenHaxl u w a Source #

Extracts data from the Env.

withEnv :: Env u w -> GenHaxl u w a -> GenHaxl u w a Source #

Returns a version of the Haxl computation which always uses the provided Env, ignoring the one specified by runHaxl.

speculate :: Env u w -> Env u w Source #

imperative :: Env u w -> Env u w Source #

JobList

data JobList u w Source #

A list of computations together with the IVar into which they should put their result.

This could be an ordinary list, but the optimised representation saves space and time.

Constructors

JobNil 
JobCons (Env u w) (GenHaxl u w a) !(IVar u w a) (JobList u w) 

addJob :: Env u w -> GenHaxl u w b -> IVar u w b -> IVar u w a -> IO () Source #

Exceptions

throw :: Exception e => e -> GenHaxl u w a Source #

Throw an exception in the Haxl monad

raise :: Exception e => e -> IO (Result u w a) Source #

catch :: Exception e => GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a Source #

Catch an exception in the Haxl monad

catchIf :: Exception e => (e -> Bool) -> GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a Source #

Catch exceptions that satisfy a predicate

try :: Exception e => GenHaxl u w a -> GenHaxl u w (Either e a) Source #

Returns Left e if the computation throws an exception e, or Right a if it returns a result a.

tryToHaxlException :: GenHaxl u w a -> GenHaxl u w (Either HaxlException a) Source #

Like try, but lifts all exceptions into the HaxlException hierarchy. Uses unsafeToHaxlException internally. Typically this is used at the top level of a Haxl computation, to ensure that all exceptions are caught.

Dumping the cache

dumpCacheAsHaskell :: GenHaxl u w String Source #

Dump the contents of the cache as Haskell code that, when compiled and run, will recreate the same cache contents. For example, the generated code looks something like this:

loadCache :: GenHaxl u w ()
loadCache = do
  cacheRequest (ListWombats 3) (Right ([1,2,3]))
  cacheRequest (CountAardvarks "abcabc") (Right (2))

dumpCacheAsHaskellFn :: String -> String -> GenHaxl u w String Source #

Dump the contents of the cache as Haskell code that, when compiled and run, will recreate the same cache contents. Does not take into account the writes done as part of the computation.

Takes the name and type for the resulting function as arguments.

CallGraph

Unsafe operations

unsafeLiftIO :: IO a -> GenHaxl u w a Source #

Under ordinary circumstances this is unnecessary; users of the Haxl monad should generally not perform arbitrary IO.

unsafeToHaxlException :: GenHaxl u w a -> GenHaxl u w a Source #

Convert exceptions in the underlying IO monad to exceptions in the Haxl monad. This is morally unsafe, because you could then catch those exceptions in Haxl and observe the underlying execution order. Not to be exposed to user code.