{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Haxl.Core.Monad
(
GenHaxl(..)
, Result(..)
, WriteTree(..)
, tellWrite
, tellWriteNoMemo
, write
, writeNoMemo
, flattenWT
, appendWTs
, mbModifyWLRef
, mapWrites
, Cont(..)
, toHaxl
, IVar(..)
, IVarContents(..)
, newIVar
, newFullIVar
, withCurrentCCS
, getIVar
, getIVarWithWrites
, putIVar
, ResultVal(..)
, done
, eitherToResult
, eitherToResultThrowIO
, CompleteReq(..)
, Env(..)
, DataCacheItem(..)
, DataCacheLookup(..)
, HaxlDataCache
, Caches
, caches
, initEnvWithData
, initEnv
, emptyEnv
, env, withEnv
, nextCallId
, sanitizeEnv
, ProfileCurrent(..)
, JobList(..)
, appendJobList
, lengthJobList
, addJob
, throw
, raise
, catch
, catchIf
, try
, tryToHaxlException
, dumpCacheAsHaskell
, dumpCacheAsHaskellFn
#ifdef PROFILING
, withCallGraph
#endif
, unsafeLiftIO, unsafeToHaxlException
) where
import Haxl.Core.Flags
import Haxl.Core.Stats
import Haxl.Core.StateStore
import Haxl.Core.Exception
import Haxl.Core.RequestStore as RequestStore
import Haxl.Core.DataCache as DataCache
import Haxl.Core.Util (trace_)
import Control.Applicative (liftA2)
import Control.Arrow (left)
import Control.Concurrent.STM
import qualified Control.Monad.Catch as Catch
import Control.Exception (Exception(..), SomeException, throwIO)
#if __GLASGOW_HASKELL__ >= 808
import Control.Monad hiding (MonadFail)
import qualified Control.Monad as CTL
#else
import Control.Monad
#endif
import qualified Control.Exception as Exception
import Data.Either (rights)
import Data.IORef
import Data.Int
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NonEmpty
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup
#endif
import qualified Data.Text as Text
import Data.Typeable
import GHC.Exts (IsString(..))
import Text.PrettyPrint hiding ((<>))
import Text.Printf
#ifdef EVENTLOG
import Control.Exception (bracket_)
import Debug.Trace (traceEventIO)
#endif
#ifdef PROFILING
import qualified Data.Map as Map
import Data.Text (Text)
import Foreign.Ptr (Ptr)
import GHC.Stack
import Haxl.Core.CallGraph
#endif
data DataCacheItem u w a = DataCacheItem (IVar u w a) {-# UNPACK #-} !CallId
type HaxlDataCache u w = DataCache (DataCacheItem u w)
newtype DataCacheLookup w =
DataCacheLookup
(forall req a . Typeable (req a)
=> req a
-> IO (Maybe (ResultVal a w)))
data Env u w = Env
{ Env u w -> HaxlDataCache u w
dataCache :: {-# UNPACK #-} !(HaxlDataCache u w)
, Env u w -> HaxlDataCache u w
memoCache :: {-# UNPACK #-} !(HaxlDataCache u w)
, Env u w -> CallId
memoKey :: {-# UNPACK #-} !CallId
, Env u w -> Flags
flags :: !Flags
, Env u w -> u
userEnv :: u
, Env u w -> IORef Stats
statsRef :: {-# UNPACK #-} !(IORef Stats)
, Env u w -> IORef CallId
statsBatchIdRef :: {-# UNPACK #-} !(IORef Int)
, Env u w -> IORef CallId
callIdRef :: {-# UNPACK #-} !(IORef CallId)
, Env u w -> ProfileCurrent
profCurrent :: ProfileCurrent
, Env u w -> IORef Profile
profRef :: {-# UNPACK #-} !(IORef Profile)
, Env u w -> StateStore
states :: StateStore
, Env u w -> IORef (RequestStore u)
reqStoreRef :: {-# UNPACK #-} !(IORef (RequestStore u))
, Env u w -> IORef (JobList u w)
runQueueRef :: {-# UNPACK #-} !(IORef (JobList u w))
, Env u w -> IORef ReqCountMap
submittedReqsRef :: {-# UNPACK #-} !(IORef ReqCountMap)
, Env u w -> TVar [CompleteReq u w]
completions :: {-# UNPACK #-} !(TVar [CompleteReq u w])
, Env u w -> IORef (WriteTree w)
writeLogsRef :: {-# UNPACK #-} !(IORef (WriteTree w))
, Env u w -> IORef (WriteTree w)
writeLogsRefNoMemo :: {-# UNPACK #-} !(IORef (WriteTree w))
, Env u w -> Maybe (DataCacheLookup w)
dataCacheFetchFallback :: !(Maybe (DataCacheLookup w))
#ifdef PROFILING
, callGraphRef :: Maybe (IORef CallGraph)
, currFunction :: QualFunction
#endif
}
data ProfileCurrent = ProfileCurrent
{ ProfileCurrent -> ProfileKey
profCurrentKey :: {-# UNPACK #-} !ProfileKey
, ProfileCurrent -> NonEmpty ProfileLabel
profLabelStack :: {-# UNPACK #-} !(NonEmpty ProfileLabel)
}
type Caches u w = (HaxlDataCache u w, HaxlDataCache u w)
caches :: Env u w -> Caches u w
caches :: Env u w -> Caches u w
caches Env u w
env = (Env u w -> HaxlDataCache u w
forall u w. Env u w -> HaxlDataCache u w
dataCache Env u w
env, Env u w -> HaxlDataCache u w
forall u w. Env u w -> HaxlDataCache u w
memoCache Env u w
env)
getMaxCallId :: HaxlDataCache u w -> IO (Maybe Int)
getMaxCallId :: HaxlDataCache u w -> IO (Maybe CallId)
getMaxCallId HaxlDataCache u w
c = do
[CallId]
callIds <- [Either SomeException CallId] -> [CallId]
forall a b. [Either a b] -> [b]
rights ([Either SomeException CallId] -> [CallId])
-> ([(TypeRep, [Either SomeException CallId])]
-> [Either SomeException CallId])
-> [(TypeRep, [Either SomeException CallId])]
-> [CallId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((TypeRep, [Either SomeException CallId])
-> [Either SomeException CallId])
-> [(TypeRep, [Either SomeException CallId])]
-> [Either SomeException CallId]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (TypeRep, [Either SomeException CallId])
-> [Either SomeException CallId]
forall a b. (a, b) -> b
snd ([(TypeRep, [Either SomeException CallId])] -> [CallId])
-> IO [(TypeRep, [Either SomeException CallId])] -> IO [CallId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
HaxlDataCache u w
-> (forall a. DataCacheItem u w a -> IO CallId)
-> IO [(TypeRep, [Either SomeException CallId])]
forall (res :: * -> *) ret.
DataCache res
-> (forall a. res a -> IO ret)
-> IO [(TypeRep, [Either SomeException ret])]
DataCache.readCache HaxlDataCache u w
c (\(DataCacheItem IVar u w a
_ CallId
i) -> CallId -> IO CallId
forall (m :: * -> *) a. Monad m => a -> m a
return CallId
i)
case [CallId]
callIds of
[] -> Maybe CallId -> IO (Maybe CallId)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe CallId
forall a. Maybe a
Nothing
[CallId]
vals -> Maybe CallId -> IO (Maybe CallId)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CallId -> IO (Maybe CallId))
-> Maybe CallId -> IO (Maybe CallId)
forall a b. (a -> b) -> a -> b
$ CallId -> Maybe CallId
forall a. a -> Maybe a
Just ([CallId] -> CallId
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [CallId]
vals)
initEnvWithData :: StateStore -> u -> Caches u w -> IO (Env u w)
initEnvWithData :: StateStore -> u -> Caches u w -> IO (Env u w)
initEnvWithData StateStore
states u
e (HaxlDataCache u w
dcache, HaxlDataCache u w
mcache) = do
CallId
newCid <- CallId -> CallId -> CallId
forall a. Ord a => a -> a -> a
max (CallId -> CallId -> CallId) -> IO CallId -> IO (CallId -> CallId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(CallId -> (CallId -> CallId) -> Maybe CallId -> CallId
forall b a. b -> (a -> b) -> Maybe a -> b
maybe CallId
0 (CallId -> CallId -> CallId
forall a. Num a => a -> a -> a
(+) CallId
1) (Maybe CallId -> CallId) -> IO (Maybe CallId) -> IO CallId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HaxlDataCache u w -> IO (Maybe CallId)
forall u w. HaxlDataCache u w -> IO (Maybe CallId)
getMaxCallId HaxlDataCache u w
dcache) IO (CallId -> CallId) -> IO CallId -> IO CallId
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
(CallId -> (CallId -> CallId) -> Maybe CallId -> CallId
forall b a. b -> (a -> b) -> Maybe a -> b
maybe CallId
0 (CallId -> CallId -> CallId
forall a. Num a => a -> a -> a
(+) CallId
1) (Maybe CallId -> CallId) -> IO (Maybe CallId) -> IO CallId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HaxlDataCache u w -> IO (Maybe CallId)
forall u w. HaxlDataCache u w -> IO (Maybe CallId)
getMaxCallId HaxlDataCache u w
mcache)
IORef CallId
ciref<- CallId -> IO (IORef CallId)
forall a. a -> IO (IORef a)
newIORef CallId
newCid
IORef Stats
sref <- Stats -> IO (IORef Stats)
forall a. a -> IO (IORef a)
newIORef Stats
emptyStats
IORef CallId
sbref <- CallId -> IO (IORef CallId)
forall a. a -> IO (IORef a)
newIORef CallId
0
IORef Profile
pref <- Profile -> IO (IORef Profile)
forall a. a -> IO (IORef a)
newIORef Profile
emptyProfile
IORef (RequestStore u)
rs <- RequestStore u -> IO (IORef (RequestStore u))
forall a. a -> IO (IORef a)
newIORef RequestStore u
forall u. RequestStore u
noRequests
IORef (JobList u w)
rq <- JobList u w -> IO (IORef (JobList u w))
forall a. a -> IO (IORef a)
newIORef JobList u w
forall u w. JobList u w
JobNil
IORef ReqCountMap
sr <- ReqCountMap -> IO (IORef ReqCountMap)
forall a. a -> IO (IORef a)
newIORef ReqCountMap
emptyReqCounts
TVar [CompleteReq u w]
comps <- [CompleteReq u w] -> IO (TVar [CompleteReq u w])
forall a. a -> IO (TVar a)
newTVarIO []
IORef (WriteTree w)
wl <- WriteTree w -> IO (IORef (WriteTree w))
forall a. a -> IO (IORef a)
newIORef WriteTree w
forall w. WriteTree w
NilWrites
IORef (WriteTree w)
wlnm <- WriteTree w -> IO (IORef (WriteTree w))
forall a. a -> IO (IORef a)
newIORef WriteTree w
forall w. WriteTree w
NilWrites
Env u w -> IO (Env u w)
forall (m :: * -> *) a. Monad m => a -> m a
return Env :: forall u w.
HaxlDataCache u w
-> HaxlDataCache u w
-> CallId
-> Flags
-> u
-> IORef Stats
-> IORef CallId
-> IORef CallId
-> ProfileCurrent
-> IORef Profile
-> StateStore
-> IORef (RequestStore u)
-> IORef (JobList u w)
-> IORef ReqCountMap
-> TVar [CompleteReq u w]
-> IORef (WriteTree w)
-> IORef (WriteTree w)
-> Maybe (DataCacheLookup w)
-> Env u w
Env
{ dataCache :: HaxlDataCache u w
dataCache = HaxlDataCache u w
dcache
, memoCache :: HaxlDataCache u w
memoCache = HaxlDataCache u w
mcache
, memoKey :: CallId
memoKey = (-CallId
1)
, flags :: Flags
flags = Flags
defaultFlags
, userEnv :: u
userEnv = u
e
, states :: StateStore
states = StateStore
states
, statsRef :: IORef Stats
statsRef = IORef Stats
sref
, statsBatchIdRef :: IORef CallId
statsBatchIdRef = IORef CallId
sbref
, profCurrent :: ProfileCurrent
profCurrent = ProfileKey -> NonEmpty ProfileLabel -> ProfileCurrent
ProfileCurrent ProfileKey
0 (NonEmpty ProfileLabel -> ProfileCurrent)
-> NonEmpty ProfileLabel -> ProfileCurrent
forall a b. (a -> b) -> a -> b
$ ProfileLabel
"MAIN" ProfileLabel -> [ProfileLabel] -> NonEmpty ProfileLabel
forall a. a -> [a] -> NonEmpty a
:| []
, callIdRef :: IORef CallId
callIdRef = IORef CallId
ciref
, profRef :: IORef Profile
profRef = IORef Profile
pref
, reqStoreRef :: IORef (RequestStore u)
reqStoreRef = IORef (RequestStore u)
rs
, runQueueRef :: IORef (JobList u w)
runQueueRef = IORef (JobList u w)
rq
, submittedReqsRef :: IORef ReqCountMap
submittedReqsRef = IORef ReqCountMap
sr
, completions :: TVar [CompleteReq u w]
completions = TVar [CompleteReq u w]
comps
, writeLogsRef :: IORef (WriteTree w)
writeLogsRef = IORef (WriteTree w)
wl
, writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRefNoMemo = IORef (WriteTree w)
wlnm
, dataCacheFetchFallback :: Maybe (DataCacheLookup w)
dataCacheFetchFallback = Maybe (DataCacheLookup w)
forall a. Maybe a
Nothing
#ifdef PROFILING
, callGraphRef = Nothing
, currFunction = mainFunction
#endif
}
initEnv :: StateStore -> u -> IO (Env u w)
initEnv :: StateStore -> u -> IO (Env u w)
initEnv StateStore
states u
e = do
DataCache (DataCacheItem u w)
dcache <- IO (DataCache (DataCacheItem u w))
forall (res :: * -> *). IO (DataCache res)
emptyDataCache
DataCache (DataCacheItem u w)
mcache <- IO (DataCache (DataCacheItem u w))
forall (res :: * -> *). IO (DataCache res)
emptyDataCache
StateStore -> u -> Caches u w -> IO (Env u w)
forall u w. StateStore -> u -> Caches u w -> IO (Env u w)
initEnvWithData StateStore
states u
e (DataCache (DataCacheItem u w)
dcache, DataCache (DataCacheItem u w)
mcache)
emptyEnv :: u -> IO (Env u w)
emptyEnv :: u -> IO (Env u w)
emptyEnv = StateStore -> u -> IO (Env u w)
forall u w. StateStore -> u -> IO (Env u w)
initEnv StateStore
stateEmpty
sanitizeEnv :: Env u w -> IO (Env u w)
sanitizeEnv :: Env u w -> IO (Env u w)
sanitizeEnv env :: Env u w
env@Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} = do
HaxlDataCache u w
sanitizedDC <- (forall a. DataCacheItem u w a -> IO Bool)
-> HaxlDataCache u w -> IO (HaxlDataCache u w)
forall (res :: * -> *).
(forall a. res a -> IO Bool) -> DataCache res -> IO (DataCache res)
DataCache.filter forall a. DataCacheItem u w a -> IO Bool
forall u w a. DataCacheItem u w a -> IO Bool
isIVarFull HaxlDataCache u w
dataCache
HaxlDataCache u w
sanitizedMC <- (forall a. DataCacheItem u w a -> IO Bool)
-> HaxlDataCache u w -> IO (HaxlDataCache u w)
forall (res :: * -> *).
(forall a. res a -> IO Bool) -> DataCache res -> IO (DataCache res)
DataCache.filter forall a. DataCacheItem u w a -> IO Bool
forall u w a. DataCacheItem u w a -> IO Bool
isIVarFull HaxlDataCache u w
memoCache
IORef (RequestStore u)
rs <- RequestStore u -> IO (IORef (RequestStore u))
forall a. a -> IO (IORef a)
newIORef RequestStore u
forall u. RequestStore u
noRequests
IORef (JobList u w)
rq <- JobList u w -> IO (IORef (JobList u w))
forall a. a -> IO (IORef a)
newIORef JobList u w
forall u w. JobList u w
JobNil
TVar [CompleteReq u w]
comps <- [CompleteReq u w] -> IO (TVar [CompleteReq u w])
forall a. a -> IO (TVar a)
newTVarIO []
IORef ReqCountMap
sr <- ReqCountMap -> IO (IORef ReqCountMap)
forall a. a -> IO (IORef a)
newIORef ReqCountMap
emptyReqCounts
Env u w -> IO (Env u w)
forall (m :: * -> *) a. Monad m => a -> m a
return Env u w
env
{ dataCache :: HaxlDataCache u w
dataCache = HaxlDataCache u w
sanitizedDC
, memoCache :: HaxlDataCache u w
memoCache = HaxlDataCache u w
sanitizedMC
, reqStoreRef :: IORef (RequestStore u)
reqStoreRef = IORef (RequestStore u)
rs
, runQueueRef :: IORef (JobList u w)
runQueueRef = IORef (JobList u w)
rq
, completions :: TVar [CompleteReq u w]
completions = TVar [CompleteReq u w]
comps
, submittedReqsRef :: IORef ReqCountMap
submittedReqsRef = IORef ReqCountMap
sr
}
where
isIVarFull :: DataCacheItem u w a -> IO Bool
isIVarFull (DataCacheItem IVar{IORef (IVarContents u w a)
ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
..} CallId
_) = do
IVarContents u w a
ivarContents <- IORef (IVarContents u w a) -> IO (IVarContents u w a)
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w a)
ivarRef
case IVarContents u w a
ivarContents of
IVarFull ResultVal a w
_ -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
IVarContents u w a
_ -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
data WriteTree w
= NilWrites
| SomeWrite w
| MergeWrites (WriteTree w) (WriteTree w)
deriving (CallId -> WriteTree w -> ShowS
[WriteTree w] -> ShowS
WriteTree w -> String
(CallId -> WriteTree w -> ShowS)
-> (WriteTree w -> String)
-> ([WriteTree w] -> ShowS)
-> Show (WriteTree w)
forall w. Show w => CallId -> WriteTree w -> ShowS
forall w. Show w => [WriteTree w] -> ShowS
forall w. Show w => WriteTree w -> String
forall a.
(CallId -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WriteTree w] -> ShowS
$cshowList :: forall w. Show w => [WriteTree w] -> ShowS
show :: WriteTree w -> String
$cshow :: forall w. Show w => WriteTree w -> String
showsPrec :: CallId -> WriteTree w -> ShowS
$cshowsPrec :: forall w. Show w => CallId -> WriteTree w -> ShowS
Show)
appendWTs :: WriteTree w -> WriteTree w -> WriteTree w
appendWTs :: WriteTree w -> WriteTree w -> WriteTree w
appendWTs WriteTree w
NilWrites WriteTree w
w = WriteTree w
w
appendWTs WriteTree w
w WriteTree w
NilWrites = WriteTree w
w
appendWTs WriteTree w
w1 WriteTree w
w2 = WriteTree w -> WriteTree w -> WriteTree w
forall w. WriteTree w -> WriteTree w -> WriteTree w
MergeWrites WriteTree w
w1 WriteTree w
w2
flattenWT :: WriteTree w -> [w]
flattenWT :: WriteTree w -> [w]
flattenWT = [w] -> WriteTree w -> [w]
forall a. [a] -> WriteTree a -> [a]
go []
where
go :: [a] -> WriteTree a -> [a]
go ![a]
ws WriteTree a
NilWrites = [a]
ws
go ![a]
ws (SomeWrite a
w) = a
w a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ws
go ![a]
ws (MergeWrites WriteTree a
w1 WriteTree a
w2) = [a] -> WriteTree a -> [a]
go ([a] -> WriteTree a -> [a]
go [a]
ws WriteTree a
w2) WriteTree a
w1
mbModifyWLRef :: WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef :: WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef WriteTree w
NilWrites IORef (WriteTree w)
_ = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
mbModifyWLRef !WriteTree w
wt IORef (WriteTree w)
ref = IORef (WriteTree w) -> (WriteTree w -> WriteTree w) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (WriteTree w)
ref (WriteTree w -> WriteTree w -> WriteTree w
forall w. WriteTree w -> WriteTree w -> WriteTree w
`appendWTs` WriteTree w
wt)
mapWriteTree :: (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree :: (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree w -> w
_ WriteTree w
NilWrites = WriteTree w
forall w. WriteTree w
NilWrites
mapWriteTree w -> w
f (SomeWrite w
w) = w -> WriteTree w
forall w. w -> WriteTree w
SomeWrite (w -> w
f w
w)
mapWriteTree w -> w
f (MergeWrites WriteTree w
wt1 WriteTree w
wt2) =
WriteTree w -> WriteTree w -> WriteTree w
forall w. WriteTree w -> WriteTree w -> WriteTree w
MergeWrites ((w -> w) -> WriteTree w -> WriteTree w
forall w. (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree w -> w
f WriteTree w
wt1) ((w -> w) -> WriteTree w -> WriteTree w
forall w. (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree w -> w
f WriteTree w
wt2)
newtype GenHaxl u w a = GenHaxl
{ GenHaxl u w a -> Env u w -> IO (Result u w a)
unHaxl :: Env u w -> IO (Result u w a) }
tellWrite :: w -> GenHaxl u w ()
tellWrite :: w -> GenHaxl u w ()
tellWrite = WriteTree w -> GenHaxl u w ()
forall w u. WriteTree w -> GenHaxl u w ()
write (WriteTree w -> GenHaxl u w ())
-> (w -> WriteTree w) -> w -> GenHaxl u w ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> WriteTree w
forall w. w -> WriteTree w
SomeWrite
write :: WriteTree w -> GenHaxl u w ()
write :: WriteTree w -> GenHaxl u w ()
write WriteTree w
wt = (Env u w -> IO (Result u w ())) -> GenHaxl u w ()
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w ())) -> GenHaxl u w ())
-> (Env u w -> IO (Result u w ())) -> GenHaxl u w ()
forall a b. (a -> b) -> a -> b
$ \Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} -> do
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef WriteTree w
wt IORef (WriteTree w)
writeLogsRef
Result u w () -> IO (Result u w ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Result u w () -> IO (Result u w ()))
-> Result u w () -> IO (Result u w ())
forall a b. (a -> b) -> a -> b
$ () -> Result u w ()
forall u w a. a -> Result u w a
Done ()
tellWriteNoMemo :: w -> GenHaxl u w ()
tellWriteNoMemo :: w -> GenHaxl u w ()
tellWriteNoMemo = WriteTree w -> GenHaxl u w ()
forall w u. WriteTree w -> GenHaxl u w ()
writeNoMemo (WriteTree w -> GenHaxl u w ())
-> (w -> WriteTree w) -> w -> GenHaxl u w ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> WriteTree w
forall w. w -> WriteTree w
SomeWrite
writeNoMemo :: WriteTree w -> GenHaxl u w ()
writeNoMemo :: WriteTree w -> GenHaxl u w ()
writeNoMemo WriteTree w
wt = (Env u w -> IO (Result u w ())) -> GenHaxl u w ()
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w ())) -> GenHaxl u w ())
-> (Env u w -> IO (Result u w ())) -> GenHaxl u w ()
forall a b. (a -> b) -> a -> b
$ \Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} -> do
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef WriteTree w
wt IORef (WriteTree w)
writeLogsRefNoMemo
Result u w () -> IO (Result u w ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Result u w () -> IO (Result u w ()))
-> Result u w () -> IO (Result u w ())
forall a b. (a -> b) -> a -> b
$ () -> Result u w ()
forall u w a. a -> Result u w a
Done ()
instance IsString a => IsString (GenHaxl u w a) where
fromString :: String -> GenHaxl u w a
fromString String
s = a -> GenHaxl u w a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> a
forall a. IsString a => String -> a
fromString String
s)
data JobList u w
= JobNil
| forall a . JobCons
(Env u w)
(GenHaxl u w a)
{-# UNPACK #-} !(IVar u w a)
(JobList u w)
appendJobList :: JobList u w -> JobList u w -> JobList u w
appendJobList :: JobList u w -> JobList u w -> JobList u w
appendJobList JobList u w
JobNil JobList u w
c = JobList u w
c
appendJobList JobList u w
c JobList u w
JobNil = JobList u w
c
appendJobList (JobCons Env u w
a GenHaxl u w a
b IVar u w a
c JobList u w
d) JobList u w
e = Env u w
-> GenHaxl u w a -> IVar u w a -> JobList u w -> JobList u w
forall u w a.
Env u w
-> GenHaxl u w a -> IVar u w a -> JobList u w -> JobList u w
JobCons Env u w
a GenHaxl u w a
b IVar u w a
c (JobList u w -> JobList u w) -> JobList u w -> JobList u w
forall a b. (a -> b) -> a -> b
$! JobList u w -> JobList u w -> JobList u w
forall u w. JobList u w -> JobList u w -> JobList u w
appendJobList JobList u w
d JobList u w
e
lengthJobList :: JobList u w -> Int
lengthJobList :: JobList u w -> CallId
lengthJobList JobList u w
JobNil = CallId
0
lengthJobList (JobCons Env u w
_ GenHaxl u w a
_ IVar u w a
_ JobList u w
j) = CallId
1 CallId -> CallId -> CallId
forall a. Num a => a -> a -> a
+ JobList u w -> CallId
forall u w. JobList u w -> CallId
lengthJobList JobList u w
j
#ifdef PROFILING
data IVar u w a = IVar
{ ivarRef :: {-# UNPACK #-} !(IORef (IVarContents u w a))
, ivarCCS :: {-# UNPACK #-} !(Ptr CostCentreStack)
#else
newtype IVar u w a = IVar
{ IVar u w a -> IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
#endif
}
data IVarContents u w a
= IVarFull (ResultVal a w)
| IVarEmpty (JobList u w)
newIVar :: IO (IVar u w a)
newIVar :: IO (IVar u w a)
newIVar = do
IORef (IVarContents u w a)
ivarRef <- IVarContents u w a -> IO (IORef (IVarContents u w a))
forall a. a -> IO (IORef a)
newIORef (JobList u w -> IVarContents u w a
forall u w a. JobList u w -> IVarContents u w a
IVarEmpty JobList u w
forall u w. JobList u w
JobNil)
#ifdef PROFILING
ivarCCS <- getCurrentCCS ivarRef
#endif
IVar u w a -> IO (IVar u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return IVar :: forall u w a. IORef (IVarContents u w a) -> IVar u w a
IVar{IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
..}
newFullIVar :: ResultVal a w -> IO (IVar u w a)
newFullIVar :: ResultVal a w -> IO (IVar u w a)
newFullIVar ResultVal a w
r = do
IORef (IVarContents u w a)
ivarRef <- IVarContents u w a -> IO (IORef (IVarContents u w a))
forall a. a -> IO (IORef a)
newIORef (ResultVal a w -> IVarContents u w a
forall u w a. ResultVal a w -> IVarContents u w a
IVarFull ResultVal a w
r)
#ifdef PROFILING
ivarCCS <- getCurrentCCS ivarRef
#endif
IVar u w a -> IO (IVar u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return IVar :: forall u w a. IORef (IVarContents u w a) -> IVar u w a
IVar{IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
ivarRef :: IORef (IVarContents u w a)
..}
withCurrentCCS :: IVar u w a -> IO (IVar u w a)
#ifdef PROFILING
withCurrentCCS ivar = do
ccs <- getCurrentCCS ivar
return ivar{ivarCCS = ccs}
#else
withCurrentCCS :: IVar u w a -> IO (IVar u w a)
withCurrentCCS = IVar u w a -> IO (IVar u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return
#endif
getIVar :: IVar u w a -> GenHaxl u w a
getIVar :: IVar u w a -> GenHaxl u w a
getIVar i :: IVar u w a
i@IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w a)
ref} = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
IVarContents u w a
e <- IORef (IVarContents u w a) -> IO (IVarContents u w a)
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w a)
ref
case IVarContents u w a
e of
IVarFull (Ok a
a WriteTree w
_wt) -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
IVarFull (ThrowHaxl SomeException
e WriteTree w
_wt) -> Env u w -> IVar u w a -> SomeException -> IO (Result u w a)
forall e u w a b.
Exception e =>
Env u w -> IVar u w a -> e -> IO (Result u w b)
raiseFromIVar Env u w
env IVar u w a
i SomeException
e
IVarFull (ThrowIO SomeException
e) -> SomeException -> IO (Result u w a)
forall e a. Exception e => e -> IO a
throwIO SomeException
e
IVarEmpty JobList u w
_ -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w a -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w a
i (IVar u w a -> Cont u w a
forall u w a. IVar u w a -> Cont u w a
Return IVar u w a
i))
getIVarApply :: IVar u w (a -> b) -> a -> GenHaxl u w b
getIVarApply :: IVar u w (a -> b) -> a -> GenHaxl u w b
getIVarApply i :: IVar u w (a -> b)
i@IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w (a -> b))
ref} a
a = (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w b)) -> GenHaxl u w b)
-> (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
IVarContents u w (a -> b)
e <- IORef (IVarContents u w (a -> b)) -> IO (IVarContents u w (a -> b))
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w (a -> b))
ref
case IVarContents u w (a -> b)
e of
IVarFull (Ok a -> b
f WriteTree w
_wt) -> Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Result u w b
forall u w a. a -> Result u w a
Done (a -> b
f a
a))
IVarFull (ThrowHaxl SomeException
e WriteTree w
_wt) -> Env u w -> IVar u w (a -> b) -> SomeException -> IO (Result u w b)
forall e u w a b.
Exception e =>
Env u w -> IVar u w a -> e -> IO (Result u w b)
raiseFromIVar Env u w
env IVar u w (a -> b)
i SomeException
e
IVarFull (ThrowIO SomeException
e) -> SomeException -> IO (Result u w b)
forall e a. Exception e => e -> IO a
throwIO SomeException
e
IVarEmpty JobList u w
_ ->
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w (a -> b) -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w (a -> b)
i (GenHaxl u w b -> Cont u w b
forall u w a. GenHaxl u w a -> Cont u w a
Cont (IVar u w (a -> b) -> a -> GenHaxl u w b
forall u w a b. IVar u w (a -> b) -> a -> GenHaxl u w b
getIVarApply IVar u w (a -> b)
i a
a)))
getIVarWithWrites :: IVar u w a -> GenHaxl u w a
getIVarWithWrites :: IVar u w a -> GenHaxl u w a
getIVarWithWrites i :: IVar u w a
i@IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w a)
ref} = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \env :: Env u w
env@Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} -> do
IVarContents u w a
e <- IORef (IVarContents u w a) -> IO (IVarContents u w a)
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w a)
ref
case IVarContents u w a
e of
IVarFull (Ok a
a WriteTree w
wt) -> do
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef WriteTree w
wt IORef (WriteTree w)
writeLogsRef
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
IVarFull (ThrowHaxl SomeException
e WriteTree w
wt) -> do
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef WriteTree w
wt IORef (WriteTree w)
writeLogsRef
Env u w -> IVar u w a -> SomeException -> IO (Result u w a)
forall e u w a b.
Exception e =>
Env u w -> IVar u w a -> e -> IO (Result u w b)
raiseFromIVar Env u w
env IVar u w a
i SomeException
e
IVarFull (ThrowIO SomeException
e) -> SomeException -> IO (Result u w a)
forall e a. Exception e => e -> IO a
throwIO SomeException
e
IVarEmpty JobList u w
_ ->
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w a -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w a
i (GenHaxl u w a -> Cont u w a
forall u w a. GenHaxl u w a -> Cont u w a
Cont (IVar u w a -> GenHaxl u w a
forall u w a. IVar u w a -> GenHaxl u w a
getIVarWithWrites IVar u w a
i)))
putIVar :: IVar u w a -> ResultVal a w -> Env u w -> IO ()
putIVar :: IVar u w a -> ResultVal a w -> Env u w -> IO ()
putIVar IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w a)
ref} ResultVal a w
a Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} = do
IVarContents u w a
e <- IORef (IVarContents u w a) -> IO (IVarContents u w a)
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w a)
ref
case IVarContents u w a
e of
IVarEmpty JobList u w
jobs -> do
IORef (IVarContents u w a) -> IVarContents u w a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (IVarContents u w a)
ref (ResultVal a w -> IVarContents u w a
forall u w a. ResultVal a w -> IVarContents u w a
IVarFull ResultVal a w
a)
IORef (JobList u w) -> (JobList u w -> JobList u w) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (JobList u w)
runQueueRef (JobList u w -> JobList u w -> JobList u w
forall u w. JobList u w -> JobList u w -> JobList u w
appendJobList JobList u w
jobs)
IVarFull{} -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE addJob #-}
addJob :: Env u w -> GenHaxl u w b -> IVar u w b -> IVar u w a -> IO ()
addJob :: Env u w -> GenHaxl u w b -> IVar u w b -> IVar u w a -> IO ()
addJob Env u w
env !GenHaxl u w b
haxl !IVar u w b
resultIVar IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w a)
ref} =
IORef (IVarContents u w a)
-> (IVarContents u w a -> IVarContents u w a) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (IVarContents u w a)
ref ((IVarContents u w a -> IVarContents u w a) -> IO ())
-> (IVarContents u w a -> IVarContents u w a) -> IO ()
forall a b. (a -> b) -> a -> b
$ \IVarContents u w a
contents ->
case IVarContents u w a
contents of
IVarEmpty JobList u w
list -> JobList u w -> IVarContents u w a
forall u w a. JobList u w -> IVarContents u w a
IVarEmpty (Env u w
-> GenHaxl u w b -> IVar u w b -> JobList u w -> JobList u w
forall u w a.
Env u w
-> GenHaxl u w a -> IVar u w a -> JobList u w -> JobList u w
JobCons Env u w
env GenHaxl u w b
haxl IVar u w b
resultIVar JobList u w
list)
IVarContents u w a
_ -> IVarContents u w a
forall a. a
addJobPanic
addJobPanic :: forall a . a
addJobPanic :: a
addJobPanic = String -> a
forall a. HasCallStack => String -> a
error String
"addJob: not empty"
data ResultVal a w
= Ok a (WriteTree w)
| ThrowHaxl SomeException (WriteTree w)
| ThrowIO SomeException
done :: Env u w -> ResultVal a w -> IO (Result u w a)
done :: Env u w -> ResultVal a w -> IO (Result u w a)
done Env u w
_ (Ok a
a WriteTree w
_) = Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
done Env u w
env (ThrowHaxl SomeException
e WriteTree w
_) = Env u w -> SomeException -> IO (Result u w a)
forall e u w a. Exception e => Env u w -> e -> IO (Result u w a)
raise Env u w
env SomeException
e
done Env u w
_ (ThrowIO SomeException
e) = SomeException -> IO (Result u w a)
forall e a. Exception e => e -> IO a
throwIO SomeException
e
eitherToResultThrowIO :: Either SomeException a -> ResultVal a w
eitherToResultThrowIO :: Either SomeException a -> ResultVal a w
eitherToResultThrowIO (Right a
a) = a -> WriteTree w -> ResultVal a w
forall a w. a -> WriteTree w -> ResultVal a w
Ok a
a WriteTree w
forall w. WriteTree w
NilWrites
eitherToResultThrowIO (Left SomeException
e)
| Just HaxlException{} <- SomeException -> Maybe HaxlException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e = SomeException -> WriteTree w -> ResultVal a w
forall a w. SomeException -> WriteTree w -> ResultVal a w
ThrowHaxl SomeException
e WriteTree w
forall w. WriteTree w
NilWrites
| Bool
otherwise = SomeException -> ResultVal a w
forall a w. SomeException -> ResultVal a w
ThrowIO SomeException
e
eitherToResult :: Either SomeException a -> ResultVal a w
eitherToResult :: Either SomeException a -> ResultVal a w
eitherToResult (Right a
a) = a -> WriteTree w -> ResultVal a w
forall a w. a -> WriteTree w -> ResultVal a w
Ok a
a WriteTree w
forall w. WriteTree w
NilWrites
eitherToResult (Left SomeException
e) = SomeException -> WriteTree w -> ResultVal a w
forall a w. SomeException -> WriteTree w -> ResultVal a w
ThrowHaxl SomeException
e WriteTree w
forall w. WriteTree w
NilWrites
data CompleteReq u w
= forall a . CompleteReq
(ResultVal a w)
!(IVar u w a)
{-# UNPACK #-} !Int64
data Result u w a
= Done a
| Throw SomeException
| forall b . Blocked
{-# UNPACK #-} !(IVar u w b)
(Cont u w a)
instance (Show a) => Show (Result u w a) where
show :: Result u w a -> String
show (Done a
a) = String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Done(%s)" ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
a
show (Throw SomeException
e) = String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Throw(%s)" ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ SomeException -> String
forall a. Show a => a -> String
show SomeException
e
show Blocked{} = String
"Blocked"
data Cont u w a
= Cont (GenHaxl u w a)
| forall b. Cont u w b :>>= (b -> GenHaxl u w a)
| forall b. (b -> a) :<$> (Cont u w b)
| Return (IVar u w a)
toHaxl :: Cont u w a -> GenHaxl u w a
toHaxl :: Cont u w a -> GenHaxl u w a
toHaxl (Cont GenHaxl u w a
haxl) = GenHaxl u w a
haxl
toHaxl (Cont u w b
m :>>= b -> GenHaxl u w a
k) = Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
forall u w b a. Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind Cont u w b
m b -> GenHaxl u w a
k
toHaxl (b -> a
f :<$> Cont u w b
x) = (b -> a) -> Cont u w b -> GenHaxl u w a
forall a b u w. (a -> b) -> Cont u w a -> GenHaxl u w b
toHaxlFmap b -> a
f Cont u w b
x
toHaxl (Return IVar u w a
i) = IVar u w a -> GenHaxl u w a
forall u w a. IVar u w a -> GenHaxl u w a
getIVar IVar u w a
i
toHaxlBind :: Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind :: Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind (Cont u w b
m :>>= b -> GenHaxl u w b
k) b -> GenHaxl u w a
k2 = Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
forall u w b a. Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind Cont u w b
m (b -> GenHaxl u w b
k (b -> GenHaxl u w b) -> (b -> GenHaxl u w a) -> b -> GenHaxl u w a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> b -> GenHaxl u w a
k2)
toHaxlBind (Cont GenHaxl u w b
haxl) b -> GenHaxl u w a
k = GenHaxl u w b
haxl GenHaxl u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> GenHaxl u w a
k
toHaxlBind (b -> b
f :<$> Cont u w b
x) b -> GenHaxl u w a
k = Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
forall u w b a. Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind Cont u w b
x (b -> GenHaxl u w a
k (b -> GenHaxl u w a) -> (b -> b) -> b -> GenHaxl u w a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> b
f)
toHaxlBind (Return IVar u w b
i) b -> GenHaxl u w a
k = IVar u w b -> GenHaxl u w b
forall u w a. IVar u w a -> GenHaxl u w a
getIVar IVar u w b
i GenHaxl u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> GenHaxl u w a
k
toHaxlFmap :: (a -> b) -> Cont u w a -> GenHaxl u w b
toHaxlFmap :: (a -> b) -> Cont u w a -> GenHaxl u w b
toHaxlFmap a -> b
f (Cont u w b
m :>>= b -> GenHaxl u w a
k) = Cont u w b -> (b -> GenHaxl u w b) -> GenHaxl u w b
forall u w b a. Cont u w b -> (b -> GenHaxl u w a) -> GenHaxl u w a
toHaxlBind Cont u w b
m (b -> GenHaxl u w a
k (b -> GenHaxl u w a) -> (a -> GenHaxl u w b) -> b -> GenHaxl u w b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> b -> GenHaxl u w b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> GenHaxl u w b) -> (a -> b) -> a -> GenHaxl u w b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
toHaxlFmap a -> b
f (Cont GenHaxl u w a
haxl) = a -> b
f (a -> b) -> GenHaxl u w a -> GenHaxl u w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenHaxl u w a
haxl
toHaxlFmap a -> b
f (b -> a
g :<$> Cont u w b
x) = (b -> b) -> Cont u w b -> GenHaxl u w b
forall a b u w. (a -> b) -> Cont u w a -> GenHaxl u w b
toHaxlFmap (a -> b
f (a -> b) -> (b -> a) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> a
g) Cont u w b
x
toHaxlFmap a -> b
f (Return IVar u w a
i) = a -> b
f (a -> b) -> GenHaxl u w a -> GenHaxl u w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IVar u w a -> GenHaxl u w a
forall u w a. IVar u w a -> GenHaxl u w a
getIVar IVar u w a
i
instance Monad (GenHaxl u w) where
return :: a -> GenHaxl u w a
return a
a = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
_env -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
GenHaxl Env u w -> IO (Result u w a)
m >>= :: GenHaxl u w a -> (a -> GenHaxl u w b) -> GenHaxl u w b
>>= a -> GenHaxl u w b
k = (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w b)) -> GenHaxl u w b)
-> (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
Result u w a
e <- Env u w -> IO (Result u w a)
m Env u w
env
case Result u w a
e of
Done a
a -> GenHaxl u w b -> Env u w -> IO (Result u w b)
forall u w a. GenHaxl u w a -> Env u w -> IO (Result u w a)
unHaxl (a -> GenHaxl u w b
k a
a) Env u w
env
Throw SomeException
e -> Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
cont -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
">>= Blocked" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (Cont u w a
cont Cont u w a -> (a -> GenHaxl u w b) -> Cont u w b
forall u w a b. Cont u w b -> (b -> GenHaxl u w a) -> Cont u w a
:>>= a -> GenHaxl u w b
k))
>> :: GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w b
(>>) = GenHaxl u w a -> GenHaxl u w b -> GenHaxl u w b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
#if __GLASGOW_HASKELL__ >= 808
instance CTL.MonadFail (GenHaxl u w) where
#endif
fail :: String -> GenHaxl u w a
fail String
msg = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
_env ->
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Result u w a -> IO (Result u w a))
-> Result u w a -> IO (Result u w a)
forall a b. (a -> b) -> a -> b
$ SomeException -> Result u w a
forall u w a. SomeException -> Result u w a
Throw (SomeException -> Result u w a) -> SomeException -> Result u w a
forall a b. (a -> b) -> a -> b
$ MonadFail -> SomeException
forall e. Exception e => e -> SomeException
toException (MonadFail -> SomeException) -> MonadFail -> SomeException
forall a b. (a -> b) -> a -> b
$ ProfileLabel -> MonadFail
MonadFail (ProfileLabel -> MonadFail) -> ProfileLabel -> MonadFail
forall a b. (a -> b) -> a -> b
$ String -> ProfileLabel
Text.pack String
msg
instance Functor (GenHaxl u w) where
fmap :: (a -> b) -> GenHaxl u w a -> GenHaxl u w b
fmap a -> b
f (GenHaxl Env u w -> IO (Result u w a)
m) = (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w b)) -> GenHaxl u w b)
-> (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
Result u w a
r <- Env u w -> IO (Result u w a)
m Env u w
env
case Result u w a
r of
Done a
a -> Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Result u w b
forall u w a. a -> Result u w a
Done (a -> b
f a
a))
Throw SomeException
e -> Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
cont -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"fmap Blocked" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (a -> b
f (a -> b) -> Cont u w a -> Cont u w b
forall u w a b. (b -> a) -> Cont u w b -> Cont u w a
:<$> Cont u w a
cont))
instance Applicative (GenHaxl u w) where
pure :: a -> GenHaxl u w a
pure = a -> GenHaxl u w a
forall (m :: * -> *) a. Monad m => a -> m a
return
GenHaxl Env u w -> IO (Result u w (a -> b))
ff <*> :: GenHaxl u w (a -> b) -> GenHaxl u w a -> GenHaxl u w b
<*> GenHaxl Env u w -> IO (Result u w a)
aa = (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w b)) -> GenHaxl u w b)
-> (Env u w -> IO (Result u w b)) -> GenHaxl u w b
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
Result u w (a -> b)
rf <- Env u w -> IO (Result u w (a -> b))
ff Env u w
env
case Result u w (a -> b)
rf of
Done a -> b
f -> do
Result u w a
ra <- Env u w -> IO (Result u w a)
aa Env u w
env
case Result u w a
ra of
Done a
a -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Done/Done" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$ Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Result u w b
forall u w a. a -> Result u w a
Done (a -> b
f a
a))
Throw SomeException
e -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Done/Throw" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$ Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
fcont -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Done/Blocked" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (a -> b
f (a -> b) -> Cont u w a -> Cont u w b
forall u w a b. (b -> a) -> Cont u w b -> Cont u w a
:<$> Cont u w a
fcont))
Throw SomeException
e -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Throw" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$ Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar1 Cont u w (a -> b)
fcont -> do
Result u w a
ra <- Env u w -> IO (Result u w a)
aa Env u w
env
case Result u w a
ra of
Done a
a -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Blocked/Done" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar1 (((a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a
a) ((a -> b) -> b) -> Cont u w (a -> b) -> Cont u w b
forall u w a b. (b -> a) -> Cont u w b -> Cont u w a
:<$> Cont u w (a -> b)
fcont))
Throw SomeException
e -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Blocked/Throw" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar1 (Cont u w (a -> b)
fcont Cont u w (a -> b) -> ((a -> b) -> GenHaxl u w b) -> Cont u w b
forall u w a b. Cont u w b -> (b -> GenHaxl u w a) -> Cont u w a
:>>= (\a -> b
_ -> SomeException -> GenHaxl u w b
forall e u w a. Exception e => e -> GenHaxl u w a
throw SomeException
e)))
Blocked IVar u w b
ivar2 Cont u w a
acont -> String -> IO (Result u w b) -> IO (Result u w b)
forall a. String -> a -> a
trace_ String
"Blocked/Blocked" (IO (Result u w b) -> IO (Result u w b))
-> IO (Result u w b) -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$
Env u w
-> IVar u w b
-> Cont u w (a -> b)
-> IVar u w b
-> Cont u w a
-> IO (Result u w b)
forall u w c a b d.
Env u w
-> IVar u w c
-> Cont u w (a -> b)
-> IVar u w d
-> Cont u w a
-> IO (Result u w b)
blockedBlocked Env u w
env IVar u w b
ivar1 Cont u w (a -> b)
fcont IVar u w b
ivar2 Cont u w a
acont
instance Semigroup a => Semigroup (GenHaxl u w a) where
<> :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a
(<>) = (a -> a -> a) -> GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>)
instance Monoid a => Monoid (GenHaxl u w a) where
mempty :: GenHaxl u w a
mempty = a -> GenHaxl u w a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Monoid a => a
mempty
mappend :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a
mappend = (a -> a -> a) -> GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Monoid a => a -> a -> a
mappend
blockedBlocked
:: Env u w
-> IVar u w c
-> Cont u w (a -> b)
-> IVar u w d
-> Cont u w a
-> IO (Result u w b)
blockedBlocked :: Env u w
-> IVar u w c
-> Cont u w (a -> b)
-> IVar u w d
-> Cont u w a
-> IO (Result u w b)
blockedBlocked Env u w
_ IVar u w c
_ (Return IVar u w (a -> b)
i) IVar u w d
ivar2 Cont u w a
acont =
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w d -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w d
ivar2 (Cont u w a
acont Cont u w a -> (a -> GenHaxl u w b) -> Cont u w b
forall u w a b. Cont u w b -> (b -> GenHaxl u w a) -> Cont u w a
:>>= IVar u w (a -> b) -> a -> GenHaxl u w b
forall u w a b. IVar u w (a -> b) -> a -> GenHaxl u w b
getIVarApply IVar u w (a -> b)
i))
blockedBlocked Env u w
_ IVar u w c
_ (b -> a -> b
g :<$> Return IVar u w b
i) IVar u w d
ivar2 Cont u w a
acont =
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w d -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w d
ivar2 (Cont u w a
acont Cont u w a -> (a -> GenHaxl u w b) -> Cont u w b
forall u w a b. Cont u w b -> (b -> GenHaxl u w a) -> Cont u w a
:>>= \ a
a -> (\b
f -> b -> a -> b
g b
f a
a) (b -> b) -> GenHaxl u w b -> GenHaxl u w b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IVar u w b -> GenHaxl u w b
forall u w a. IVar u w a -> GenHaxl u w a
getIVar IVar u w b
i))
blockedBlocked Env u w
env IVar u w c
ivar1 Cont u w (a -> b)
fcont IVar u w d
ivar2 Cont u w a
acont = do
IVar u w (a -> b)
i <- IO (IVar u w (a -> b))
forall u w a. IO (IVar u w a)
newIVar
Env u w
-> GenHaxl u w (a -> b) -> IVar u w (a -> b) -> IVar u w c -> IO ()
forall u w b a.
Env u w -> GenHaxl u w b -> IVar u w b -> IVar u w a -> IO ()
addJob Env u w
env (Cont u w (a -> b) -> GenHaxl u w (a -> b)
forall u w a. Cont u w a -> GenHaxl u w a
toHaxl Cont u w (a -> b)
fcont) IVar u w (a -> b)
i IVar u w c
ivar1
let cont :: Cont u w b
cont = Cont u w a
acont Cont u w a -> (a -> GenHaxl u w b) -> Cont u w b
forall u w a b. Cont u w b -> (b -> GenHaxl u w a) -> Cont u w a
:>>= \a
a -> IVar u w (a -> b) -> a -> GenHaxl u w b
forall u w a b. IVar u w (a -> b) -> a -> GenHaxl u w b
getIVarApply IVar u w (a -> b)
i a
a
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w d -> Cont u w b -> Result u w b
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w d
ivar2 Cont u w b
cont)
env :: (Env u w -> a) -> GenHaxl u w a
env :: (Env u w -> a) -> GenHaxl u w a
env Env u w -> a
f = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done (Env u w -> a
f Env u w
env))
withEnv :: Env u w -> GenHaxl u w a -> GenHaxl u w a
withEnv :: Env u w -> GenHaxl u w a -> GenHaxl u w a
withEnv Env u w
newEnv (GenHaxl Env u w -> IO (Result u w a)
m) = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
_env -> do
Result u w a
r <- Env u w -> IO (Result u w a)
m Env u w
newEnv
case Result u w a
r of
Done a
a -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
Throw SomeException
e -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w a
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
k ->
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (GenHaxl u w a -> Cont u w a
forall u w a. GenHaxl u w a -> Cont u w a
Cont (Env u w -> GenHaxl u w a -> GenHaxl u w a
forall u w a. Env u w -> GenHaxl u w a -> GenHaxl u w a
withEnv Env u w
newEnv (Cont u w a -> GenHaxl u w a
forall u w a. Cont u w a -> GenHaxl u w a
toHaxl Cont u w a
k))))
nextCallId :: Env u w -> IO CallId
nextCallId :: Env u w -> IO CallId
nextCallId Env u w
env = IORef CallId -> (CallId -> (CallId, CallId)) -> IO CallId
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' (Env u w -> IORef CallId
forall u w. Env u w -> IORef CallId
callIdRef Env u w
env) ((CallId -> (CallId, CallId)) -> IO CallId)
-> (CallId -> (CallId, CallId)) -> IO CallId
forall a b. (a -> b) -> a -> b
$ \CallId
x -> (CallId
xCallId -> CallId -> CallId
forall a. Num a => a -> a -> a
+CallId
1,CallId
xCallId -> CallId -> CallId
forall a. Num a => a -> a -> a
+CallId
1)
mapWrites :: (w -> w) -> GenHaxl u w a -> GenHaxl u w a
mapWrites :: (w -> w) -> GenHaxl u w a -> GenHaxl u w a
mapWrites w -> w
f GenHaxl u w a
action = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
curEnv -> do
IORef (WriteTree w)
wlogs <- WriteTree w -> IO (IORef (WriteTree w))
forall a. a -> IO (IORef a)
newIORef WriteTree w
forall w. WriteTree w
NilWrites
IORef (WriteTree w)
wlogsNoMemo <- WriteTree w -> IO (IORef (WriteTree w))
forall a. a -> IO (IORef a)
newIORef WriteTree w
forall w. WriteTree w
NilWrites
let
!newEnv :: Env u w
newEnv = Env u w
curEnv { writeLogsRef :: IORef (WriteTree w)
writeLogsRef = IORef (WriteTree w)
wlogs, writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRefNoMemo = IORef (WriteTree w)
wlogsNoMemo }
GenHaxl u w a -> Env u w -> IO (Result u w a)
forall u w a. GenHaxl u w a -> Env u w -> IO (Result u w a)
unHaxl (Env u w -> Env u w -> GenHaxl u w a -> GenHaxl u w a
mapWritesImpl Env u w
curEnv Env u w
newEnv GenHaxl u w a
action) Env u w
newEnv
where
mapWritesImpl :: Env u w -> Env u w -> GenHaxl u w a -> GenHaxl u w a
mapWritesImpl Env u w
oldEnv Env u w
curEnv (GenHaxl Env u w -> IO (Result u w a)
m) = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
_ -> do
let
pushTransformedWrites :: IO ()
pushTransformedWrites = do
WriteTree w
wt <- IORef (WriteTree w) -> IO (WriteTree w)
forall a. IORef a -> IO a
readIORef (IORef (WriteTree w) -> IO (WriteTree w))
-> IORef (WriteTree w) -> IO (WriteTree w)
forall a b. (a -> b) -> a -> b
$ Env u w -> IORef (WriteTree w)
forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef Env u w
curEnv
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef ((w -> w) -> WriteTree w -> WriteTree w
forall w. (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree w -> w
f WriteTree w
wt) (Env u w -> IORef (WriteTree w)
forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef Env u w
oldEnv)
WriteTree w
wtNoMemo <- IORef (WriteTree w) -> IO (WriteTree w)
forall a. IORef a -> IO a
readIORef (IORef (WriteTree w) -> IO (WriteTree w))
-> IORef (WriteTree w) -> IO (WriteTree w)
forall a b. (a -> b) -> a -> b
$ Env u w -> IORef (WriteTree w)
forall u w. Env u w -> IORef (WriteTree w)
writeLogsRefNoMemo Env u w
curEnv
WriteTree w -> IORef (WriteTree w) -> IO ()
forall w. WriteTree w -> IORef (WriteTree w) -> IO ()
mbModifyWLRef ((w -> w) -> WriteTree w -> WriteTree w
forall w. (w -> w) -> WriteTree w -> WriteTree w
mapWriteTree w -> w
f WriteTree w
wtNoMemo) (Env u w -> IORef (WriteTree w)
forall u w. Env u w -> IORef (WriteTree w)
writeLogsRefNoMemo Env u w
oldEnv)
Result u w a
r <- Env u w -> IO (Result u w a)
m Env u w
curEnv
case Result u w a
r of
Done a
a -> IO ()
pushTransformedWrites IO () -> IO (Result u w a) -> IO (Result u w a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
Throw SomeException
e -> IO ()
pushTransformedWrites IO () -> IO (Result u w a) -> IO (Result u w a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w a
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
k -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return
(IVar u w b -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (GenHaxl u w a -> Cont u w a
forall u w a. GenHaxl u w a -> Cont u w a
Cont (Env u w -> Env u w -> GenHaxl u w a -> GenHaxl u w a
mapWritesImpl Env u w
oldEnv Env u w
curEnv (Cont u w a -> GenHaxl u w a
forall u w a. Cont u w a -> GenHaxl u w a
toHaxl Cont u w a
k))))
#ifdef PROFILING
withCallGraph
:: Typeable a
=> (a -> Maybe Text)
-> QualFunction
-> GenHaxl u w a
-> GenHaxl u w a
withCallGraph toText f a = do
coreEnv <- env id
value <- withEnv coreEnv{currFunction = f} a
case callGraphRef coreEnv of
Just graph -> unsafeLiftIO $ modifyIORef' graph
(updateCallGraph (f, currFunction coreEnv) (toText value))
_ -> throw $ CriticalError
"withCallGraph called without an IORef CallGraph"
return value
where
updateCallGraph :: FunctionCall -> Maybe Text -> CallGraph -> CallGraph
updateCallGraph fnCall@(childQFunc, _) (Just value) (edgeList, valueMap) =
(fnCall : edgeList, Map.insert childQFunc value valueMap)
updateCallGraph fnCall Nothing (edgeList, valueMap) =
(fnCall : edgeList, valueMap)
#endif
throw :: Exception e => e -> GenHaxl u w a
throw :: e -> GenHaxl u w a
throw e
e = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> Env u w -> e -> IO (Result u w a)
forall e u w a. Exception e => Env u w -> e -> IO (Result u w a)
raise Env u w
env e
e
raise :: Exception e => Env u w -> e -> IO (Result u w a)
raise :: Env u w -> e -> IO (Result u w a)
raise Env u w
env e
e = Env u w -> SomeException -> IO (Result u w a)
forall u w b. Env u w -> SomeException -> IO (Result u w b)
raiseImpl Env u w
env (e -> SomeException
forall e. Exception e => e -> SomeException
toException e
e)
#ifdef PROFILING
currentCallStack
#endif
raiseFromIVar :: Exception e => Env u w -> IVar u w a -> e -> IO (Result u w b)
#ifdef PROFILING
raiseFromIVar env IVar{..} e =
raiseImpl env (toException e) (ccsToStrings ivarCCS)
#else
raiseFromIVar :: Env u w -> IVar u w a -> e -> IO (Result u w b)
raiseFromIVar Env u w
env IVar u w a
_ivar e
e = Env u w -> SomeException -> IO (Result u w b)
forall u w b. Env u w -> SomeException -> IO (Result u w b)
raiseImpl Env u w
env (e -> SomeException
forall e. Exception e => e -> SomeException
toException e
e)
#endif
{-# INLINE raiseImpl #-}
#ifdef PROFILING
raiseImpl :: Env u w -> SomeException -> IO [String] -> IO (Result u w b)
raiseImpl Env{..} e getCostCentreStack
#else
raiseImpl :: Env u w -> SomeException -> IO (Result u w b)
raiseImpl :: Env u w -> SomeException -> IO (Result u w b)
raiseImpl Env{u
CallId
Maybe (DataCacheLookup w)
TVar [CompleteReq u w]
IORef CallId
IORef Profile
IORef Stats
IORef ReqCountMap
IORef (RequestStore u)
IORef (JobList u w)
IORef (WriteTree w)
HaxlDataCache u w
Flags
StateStore
ProfileCurrent
dataCacheFetchFallback :: Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: IORef (WriteTree w)
writeLogsRef :: IORef (WriteTree w)
completions :: TVar [CompleteReq u w]
submittedReqsRef :: IORef ReqCountMap
runQueueRef :: IORef (JobList u w)
reqStoreRef :: IORef (RequestStore u)
states :: StateStore
profRef :: IORef Profile
profCurrent :: ProfileCurrent
callIdRef :: IORef CallId
statsBatchIdRef :: IORef CallId
statsRef :: IORef Stats
userEnv :: u
flags :: Flags
memoKey :: CallId
memoCache :: HaxlDataCache u w
dataCache :: HaxlDataCache u w
dataCacheFetchFallback :: forall u w. Env u w -> Maybe (DataCacheLookup w)
writeLogsRefNoMemo :: forall u w. Env u w -> IORef (WriteTree w)
writeLogsRef :: forall u w. Env u w -> IORef (WriteTree w)
completions :: forall u w. Env u w -> TVar [CompleteReq u w]
submittedReqsRef :: forall u w. Env u w -> IORef ReqCountMap
runQueueRef :: forall u w. Env u w -> IORef (JobList u w)
reqStoreRef :: forall u w. Env u w -> IORef (RequestStore u)
states :: forall u w. Env u w -> StateStore
profRef :: forall u w. Env u w -> IORef Profile
profCurrent :: forall u w. Env u w -> ProfileCurrent
callIdRef :: forall u w. Env u w -> IORef CallId
statsBatchIdRef :: forall u w. Env u w -> IORef CallId
statsRef :: forall u w. Env u w -> IORef Stats
userEnv :: forall u w. Env u w -> u
flags :: forall u w. Env u w -> Flags
memoKey :: forall u w. Env u w -> CallId
memoCache :: forall u w. Env u w -> HaxlDataCache u w
dataCache :: forall u w. Env u w -> HaxlDataCache u w
..} SomeException
e
#endif
| ReportFlag -> ReportFlags -> Bool
testReportFlag ReportFlag
ReportExceptionLabelStack (ReportFlags -> Bool) -> ReportFlags -> Bool
forall a b. (a -> b) -> a -> b
$ Flags -> ReportFlags
report Flags
flags
, Just (HaxlException Maybe [ProfileLabel]
Nothing e
h) <- SomeException -> Maybe HaxlException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e = do
let stk :: [ProfileLabel]
stk = NonEmpty ProfileLabel -> [ProfileLabel]
forall a. NonEmpty a -> [a]
NonEmpty.toList (NonEmpty ProfileLabel -> [ProfileLabel])
-> NonEmpty ProfileLabel -> [ProfileLabel]
forall a b. (a -> b) -> a -> b
$ ProfileCurrent -> NonEmpty ProfileLabel
profLabelStack ProfileCurrent
profCurrent
Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Result u w b -> IO (Result u w b))
-> Result u w b -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$ SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw (SomeException -> Result u w b) -> SomeException -> Result u w b
forall a b. (a -> b) -> a -> b
$ HaxlException -> SomeException
forall e. Exception e => e -> SomeException
toException (HaxlException -> SomeException) -> HaxlException -> SomeException
forall a b. (a -> b) -> a -> b
$ Maybe [ProfileLabel] -> e -> HaxlException
forall e.
MiddleException e =>
Maybe [ProfileLabel] -> e -> HaxlException
HaxlException ([ProfileLabel] -> Maybe [ProfileLabel]
forall a. a -> Maybe a
Just [ProfileLabel]
stk) e
h
#ifdef PROFILING
| Just (HaxlException Nothing h) <- fromException e = do
stk <- reverse . map Text.pack <$> getCostCentreStack
return $ Throw $ toException $ HaxlException (Just stk) h
#endif
| Bool
otherwise = Result u w b -> IO (Result u w b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Result u w b -> IO (Result u w b))
-> Result u w b -> IO (Result u w b)
forall a b. (a -> b) -> a -> b
$ SomeException -> Result u w b
forall u w a. SomeException -> Result u w a
Throw SomeException
e
catch :: Exception e => GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catch :: GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catch (GenHaxl Env u w -> IO (Result u w a)
m) e -> GenHaxl u w a
h = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
Result u w a
r <- Env u w -> IO (Result u w a)
m Env u w
env
case Result u w a
r of
Done a
a -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Result u w a
forall u w a. a -> Result u w a
Done a
a)
Throw SomeException
e | Just e
e' <- SomeException -> Maybe e
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e -> GenHaxl u w a -> Env u w -> IO (Result u w a)
forall u w a. GenHaxl u w a -> Env u w -> IO (Result u w a)
unHaxl (e -> GenHaxl u w a
h e
e') Env u w
env
| Bool
otherwise -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w a
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
Blocked IVar u w b
ivar Cont u w a
k -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
ivar (GenHaxl u w a -> Cont u w a
forall u w a. GenHaxl u w a -> Cont u w a
Cont (GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
forall e u w a.
Exception e =>
GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catch (Cont u w a -> GenHaxl u w a
forall u w a. Cont u w a -> GenHaxl u w a
toHaxl Cont u w a
k) e -> GenHaxl u w a
h)))
catchIf
:: Exception e => (e -> Bool) -> GenHaxl u w a -> (e -> GenHaxl u w a)
-> GenHaxl u w a
catchIf :: (e -> Bool)
-> GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catchIf e -> Bool
cond GenHaxl u w a
haxl e -> GenHaxl u w a
handler =
GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
forall e u w a.
Exception e =>
GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catch GenHaxl u w a
haxl ((e -> GenHaxl u w a) -> GenHaxl u w a)
-> (e -> GenHaxl u w a) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \e
e -> if e -> Bool
cond e
e then e -> GenHaxl u w a
handler e
e else e -> GenHaxl u w a
forall e u w a. Exception e => e -> GenHaxl u w a
throw e
e
try :: Exception e => GenHaxl u w a -> GenHaxl u w (Either e a)
try :: GenHaxl u w a -> GenHaxl u w (Either e a)
try GenHaxl u w a
haxl = (a -> Either e a
forall a b. b -> Either a b
Right (a -> Either e a) -> GenHaxl u w a -> GenHaxl u w (Either e a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenHaxl u w a
haxl) GenHaxl u w (Either e a)
-> (e -> GenHaxl u w (Either e a)) -> GenHaxl u w (Either e a)
forall e u w a.
Exception e =>
GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
`catch` (Either e a -> GenHaxl u w (Either e a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either e a -> GenHaxl u w (Either e a))
-> (e -> Either e a) -> e -> GenHaxl u w (Either e a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Either e a
forall a b. a -> Either a b
Left)
instance Catch.MonadThrow (GenHaxl u w) where throwM :: e -> GenHaxl u w a
throwM = e -> GenHaxl u w a
forall e u w a. Exception e => e -> GenHaxl u w a
Haxl.Core.Monad.throw
instance Catch.MonadCatch (GenHaxl u w) where catch :: GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
catch = GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
forall e u w a.
Exception e =>
GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
Haxl.Core.Monad.catch
unsafeLiftIO :: IO a -> GenHaxl u w a
unsafeLiftIO :: IO a -> GenHaxl u w a
unsafeLiftIO IO a
m = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
_env -> a -> Result u w a
forall u w a. a -> Result u w a
Done (a -> Result u w a) -> IO a -> IO (Result u w a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO a
m
unsafeToHaxlException :: GenHaxl u w a -> GenHaxl u w a
unsafeToHaxlException :: GenHaxl u w a -> GenHaxl u w a
unsafeToHaxlException (GenHaxl Env u w -> IO (Result u w a)
m) = (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall u w a. (Env u w -> IO (Result u w a)) -> GenHaxl u w a
GenHaxl ((Env u w -> IO (Result u w a)) -> GenHaxl u w a)
-> (Env u w -> IO (Result u w a)) -> GenHaxl u w a
forall a b. (a -> b) -> a -> b
$ \Env u w
env -> do
Result u w a
r <- Env u w -> IO (Result u w a)
m Env u w
env IO (Result u w a)
-> (SomeException -> IO (Result u w a)) -> IO (Result u w a)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`Exception.catch` \SomeException
e -> do
SomeException -> IO ()
rethrowAsyncExceptions SomeException
e
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> Result u w a
forall u w a. SomeException -> Result u w a
Throw SomeException
e)
case Result u w a
r of
Blocked IVar u w b
cvar Cont u w a
c ->
Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return (IVar u w b -> Cont u w a -> Result u w a
forall u w a b. IVar u w b -> Cont u w a -> Result u w a
Blocked IVar u w b
cvar (GenHaxl u w a -> Cont u w a
forall u w a. GenHaxl u w a -> Cont u w a
Cont (GenHaxl u w a -> GenHaxl u w a
forall u w a. GenHaxl u w a -> GenHaxl u w a
unsafeToHaxlException (Cont u w a -> GenHaxl u w a
forall u w a. Cont u w a -> GenHaxl u w a
toHaxl Cont u w a
c))))
Result u w a
other -> Result u w a -> IO (Result u w a)
forall (m :: * -> *) a. Monad m => a -> m a
return Result u w a
other
tryToHaxlException :: GenHaxl u w a -> GenHaxl u w (Either HaxlException a)
tryToHaxlException :: GenHaxl u w a -> GenHaxl u w (Either HaxlException a)
tryToHaxlException GenHaxl u w a
h = (SomeException -> HaxlException)
-> Either SomeException a -> Either HaxlException a
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left SomeException -> HaxlException
asHaxlException (Either SomeException a -> Either HaxlException a)
-> GenHaxl u w (Either SomeException a)
-> GenHaxl u w (Either HaxlException a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenHaxl u w a -> GenHaxl u w (Either SomeException a)
forall e u w a.
Exception e =>
GenHaxl u w a -> GenHaxl u w (Either e a)
try (GenHaxl u w a -> GenHaxl u w a
forall u w a. GenHaxl u w a -> GenHaxl u w a
unsafeToHaxlException GenHaxl u w a
h)
dumpCacheAsHaskell :: GenHaxl u w String
dumpCacheAsHaskell :: GenHaxl u w String
dumpCacheAsHaskell =
String -> String -> String -> GenHaxl u w String
forall u w. String -> String -> String -> GenHaxl u w String
dumpCacheAsHaskellFn String
"loadCache" String
"GenHaxl u w ()" String
"cacheRequest"
dumpCacheAsHaskellFn :: String -> String -> String -> GenHaxl u w String
dumpCacheAsHaskellFn :: String -> String -> String -> GenHaxl u w String
dumpCacheAsHaskellFn String
fnName String
fnType String
cacheFn = do
HaxlDataCache u w
cache <- (Env u w -> HaxlDataCache u w) -> GenHaxl u w (HaxlDataCache u w)
forall u w a. (Env u w -> a) -> GenHaxl u w a
env Env u w -> HaxlDataCache u w
forall u w. Env u w -> HaxlDataCache u w
dataCache
let
readIVar :: DataCacheItem u w b -> IO (Maybe (Either SomeException b))
readIVar (DataCacheItem IVar{ivarRef :: forall u w a. IVar u w a -> IORef (IVarContents u w a)
ivarRef = !IORef (IVarContents u w b)
ref} CallId
_) = do
IVarContents u w b
r <- IORef (IVarContents u w b) -> IO (IVarContents u w b)
forall a. IORef a -> IO a
readIORef IORef (IVarContents u w b)
ref
case IVarContents u w b
r of
IVarFull (Ok b
a WriteTree w
_) -> Maybe (Either SomeException b)
-> IO (Maybe (Either SomeException b))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SomeException b -> Maybe (Either SomeException b)
forall a. a -> Maybe a
Just (b -> Either SomeException b
forall a b. b -> Either a b
Right b
a))
IVarFull (ThrowHaxl SomeException
e WriteTree w
_) -> Maybe (Either SomeException b)
-> IO (Maybe (Either SomeException b))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SomeException b -> Maybe (Either SomeException b)
forall a. a -> Maybe a
Just (SomeException -> Either SomeException b
forall a b. a -> Either a b
Left SomeException
e))
IVarFull (ThrowIO SomeException
e) -> Maybe (Either SomeException b)
-> IO (Maybe (Either SomeException b))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SomeException b -> Maybe (Either SomeException b)
forall a. a -> Maybe a
Just (SomeException -> Either SomeException b
forall a b. a -> Either a b
Left SomeException
e))
IVarEmpty JobList u w
_ -> Maybe (Either SomeException b)
-> IO (Maybe (Either SomeException b))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Either SomeException b)
forall a. Maybe a
Nothing
mk_cr :: (String, Either SomeException String) -> Doc
mk_cr (String
req, Either SomeException String
res) =
String -> Doc
text String
cacheFn Doc -> Doc -> Doc
<+> Doc -> Doc
parens (String -> Doc
text String
req) Doc -> Doc -> Doc
<+> Doc -> Doc
parens (Either SomeException String -> Doc
forall a. Show a => Either a String -> Doc
result Either SomeException String
res)
result :: Either a String -> Doc
result (Left a
e) = String -> Doc
text String
"except" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (String -> Doc
text (a -> String
forall a. Show a => a -> String
show a
e))
result (Right String
s) = String -> Doc
text String
"Right" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (String -> Doc
text String
s)
[(TypeRep, [(String, Either SomeException String)])]
entries <- IO [(TypeRep, [(String, Either SomeException String)])]
-> GenHaxl u w [(TypeRep, [(String, Either SomeException String)])]
forall a u w. IO a -> GenHaxl u w a
unsafeLiftIO (IO [(TypeRep, [(String, Either SomeException String)])]
-> GenHaxl
u w [(TypeRep, [(String, Either SomeException String)])])
-> IO [(TypeRep, [(String, Either SomeException String)])]
-> GenHaxl u w [(TypeRep, [(String, Either SomeException String)])]
forall a b. (a -> b) -> a -> b
$ do
HaxlDataCache u w
-> (forall a.
DataCacheItem u w a -> IO (Maybe (Either SomeException a)))
-> IO [(TypeRep, [(String, Either SomeException String)])]
forall (res :: * -> *).
DataCache res
-> (forall a. res a -> IO (Maybe (Either SomeException a)))
-> IO [(TypeRep, [(String, Either SomeException String)])]
showCache HaxlDataCache u w
cache forall a.
DataCacheItem u w a -> IO (Maybe (Either SomeException a))
forall u w b.
DataCacheItem u w b -> IO (Maybe (Either SomeException b))
readIVar
let
body :: Doc
body = if [(TypeRep, [(String, Either SomeException String)])] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(TypeRep, [(String, Either SomeException String)])]
entries
then String -> Doc
text String
"return ()"
else [Doc] -> Doc
vcat (((String, Either SomeException String) -> Doc)
-> [(String, Either SomeException String)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (String, Either SomeException String) -> Doc
mk_cr (((TypeRep, [(String, Either SomeException String)])
-> [(String, Either SomeException String)])
-> [(TypeRep, [(String, Either SomeException String)])]
-> [(String, Either SomeException String)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (TypeRep, [(String, Either SomeException String)])
-> [(String, Either SomeException String)]
forall a b. (a, b) -> b
snd [(TypeRep, [(String, Either SomeException String)])]
entries))
String -> GenHaxl u w String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> GenHaxl u w String) -> String -> GenHaxl u w String
forall a b. (a -> b) -> a -> b
$ Doc -> String
forall a. Show a => a -> String
show (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$
String -> Doc
text (String
fnName String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" :: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
fnType) Doc -> Doc -> Doc
$$
String -> Doc
text (String
fnName String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" = do") Doc -> Doc -> Doc
$$
CallId -> Doc -> Doc
nest CallId
2 Doc
body Doc -> Doc -> Doc
$$
String -> Doc
text String
""