{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module Haxl.DataSource.ConcurrentIO
( mkConcurrentIOState
, ConcurrentIO(..)
) where
import Control.Concurrent
import Control.Exception as Exception
import Control.Monad
import qualified Data.Text as Text
import Data.Typeable
import Haxl.Core
class ConcurrentIO tag where
data ConcurrentIOReq tag a
performIO :: ConcurrentIOReq tag a -> IO a
deriving instance Typeable ConcurrentIOReq
instance (Typeable tag) => StateKey (ConcurrentIOReq tag) where
data State (ConcurrentIOReq tag) = ConcurrentIOState
getStateType _ = typeRep (Proxy :: Proxy ConcurrentIOReq)
mkConcurrentIOState :: IO (State (ConcurrentIOReq ()))
mkConcurrentIOState = return ConcurrentIOState
instance Typeable tag => DataSourceName (ConcurrentIOReq tag) where
dataSourceName _ =
Text.pack (show (typeRepTyCon (typeRep (Proxy :: Proxy tag))))
instance
(Typeable tag, ShowP (ConcurrentIOReq tag), ConcurrentIO tag)
=> DataSource u (ConcurrentIOReq tag)
where
fetch _state _flags _u = BackgroundFetch $ \bfs -> do
forM_ bfs $ \(BlockedFetch req rv) ->
mask $ \unmask ->
forkFinally (unmask (performIO req)) (putResultFromChildThread rv)