{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
module Managed.Agent
( fromList
, toList
, (!)
, (!?)
, invoke
, ids
, invokeUnsafe
, describe
, describeEither
, describeHuman
) where
import qualified Data.Map as M
import Data.Managed
import Control.DeepSeq (NFData, force)
import Control.Exception (catch, evaluate, toException)
import Control.Monad.Catch (try)
import Managed.Exception
import Managed.ProbeDescription
import System.IO.Error (catchIOError)
fromList :: [(ProbeID, Probe e)] -> Agent e
fromList :: [(ProbeID, Probe e)] -> Agent e
fromList = [(ProbeID, Probe e)] -> Agent e
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
toList :: Agent e -> [(ProbeID, Probe e)]
toList :: Agent e -> [(ProbeID, Probe e)]
toList = Agent e -> [(ProbeID, Probe e)]
forall k a. Map k a -> [(k, a)]
M.toList
infixl 9 !, !?
(!) :: Agent e -> ProbeID -> Probe e
(!) = Agent e -> ProbeID -> Probe e
forall k a. Ord k => Map k a -> k -> a
(M.!)
(!?) :: Agent e -> ProbeID -> Maybe (Probe e)
!? :: Agent e -> ProbeID -> Maybe (Probe e)
(!?) = Agent e -> ProbeID -> Maybe (Probe e)
forall k a. Ord k => Map k a -> k -> Maybe a
(M.!?)
invoke ::
(NFData (Out e))
=> Agent e
-> ProbeID
-> [In e]
-> IO (Either AgentException (Out e))
invoke :: Agent e -> ProbeID -> [In e] -> IO (Either AgentException (Out e))
invoke Agent e
a ProbeID
p [In e]
i = IO (Out e) -> IO (Either AgentException (Out e))
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (IO (Out e) -> IO (Either AgentException (Out e)))
-> IO (Out e) -> IO (Either AgentException (Out e))
forall a b. (a -> b) -> a -> b
$ Agent e -> ProbeID -> [In e] -> IO (Out e)
forall e.
NFData (Out e) =>
Agent e -> ProbeID -> [In e] -> IO (Out e)
invokeUnsafe Agent e
a ProbeID
p [In e]
i
invokeUnsafe :: (NFData (Out e)) => Agent e -> ProbeID -> [In e] -> IO (Out e)
invokeUnsafe :: Agent e -> ProbeID -> [In e] -> IO (Out e)
invokeUnsafe Agent e
agent ProbeID
pid [In e]
input = Agent e -> ProbeID -> IO (Probe e)
forall e. Agent e -> ProbeID -> IO (Probe e)
findOrThrow Agent e
agent ProbeID
pid IO (Probe e) -> (Probe e -> IO (Out e)) -> IO (Out e)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [In e] -> Probe e -> IO (Out e)
forall e. NFData (Out e) => [In e] -> Probe e -> IO (Out e)
callStrict [In e]
input
ids :: Agent e -> [ProbeID]
ids :: Agent e -> [ProbeID]
ids = ((ProbeID, Probe e) -> ProbeID)
-> [(ProbeID, Probe e)] -> [ProbeID]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map (ProbeID, Probe e) -> ProbeID
forall a b. (a, b) -> a
fst ([(ProbeID, Probe e)] -> [ProbeID])
-> (Agent e -> [(ProbeID, Probe e)]) -> Agent e -> [ProbeID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Agent e -> [(ProbeID, Probe e)]
forall e. Agent e -> [(ProbeID, Probe e)]
toList
describe :: Agent e -> ProbeID -> Maybe ProbeDescription
describe :: Agent e -> ProbeID -> Maybe ProbeDescription
describe Agent e
agent ProbeID
pid = ProbeID -> Probe e -> ProbeDescription
forall e. ProbeID -> Probe e -> ProbeDescription
mkDescription ProbeID
pid (Probe e -> ProbeDescription)
-> Maybe (Probe e) -> Maybe ProbeDescription
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Agent e
agent Agent e -> ProbeID -> Maybe (Probe e)
forall e. Agent e -> ProbeID -> Maybe (Probe e)
!? ProbeID
pid
describeEither :: Agent e -> ProbeID -> Either AgentException ProbeDescription
describeEither :: Agent e -> ProbeID -> Either AgentException ProbeDescription
describeEither Agent e
agent ProbeID
pid =
case Agent e -> ProbeID -> Maybe ProbeDescription
forall e. Agent e -> ProbeID -> Maybe ProbeDescription
describe Agent e
agent ProbeID
pid of
Maybe ProbeDescription
Nothing -> AgentException -> Either AgentException ProbeDescription
forall a b. a -> Either a b
Left (AgentException -> Either AgentException ProbeDescription)
-> AgentException -> Either AgentException ProbeDescription
forall a b. (a -> b) -> a -> b
$ ProbeID -> AgentException
badProbeID ProbeID
pid
Just ProbeDescription
res -> ProbeDescription -> Either AgentException ProbeDescription
forall a b. b -> Either a b
Right ProbeDescription
res
describeHuman :: Agent e -> ProbeID -> Maybe String
describeHuman :: Agent e -> ProbeID -> Maybe ProbeID
describeHuman Agent e
agent ProbeID
pid = ProbeDescription -> ProbeID
human (ProbeDescription -> ProbeID)
-> Maybe ProbeDescription -> Maybe ProbeID
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Agent e -> ProbeID -> Maybe ProbeDescription
forall e. Agent e -> ProbeID -> Maybe ProbeDescription
describe Agent e
agent ProbeID
pid
findOrThrow :: Agent e -> ProbeID -> IO (Probe e)
findOrThrow :: Agent e -> ProbeID -> IO (Probe e)
findOrThrow Agent e
agent ProbeID
pid =
case Agent e
agent Agent e -> ProbeID -> Maybe (Probe e)
forall e. Agent e -> ProbeID -> Maybe (Probe e)
!? ProbeID
pid of
Maybe (Probe e)
Nothing -> AgentException -> IO (Probe e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (AgentException -> IO (Probe e)) -> AgentException -> IO (Probe e)
forall a b. (a -> b) -> a -> b
$ ProbeID -> AgentException
badProbeID ProbeID
pid
Just Probe e
probe -> Probe e -> IO (Probe e)
forall (m :: * -> *) a. Monad m => a -> m a
return Probe e
probe
callStrict :: (NFData (Out e)) => [In e] -> Probe e -> IO (Out e)
callStrict :: [In e] -> Probe e -> IO (Out e)
callStrict [In e]
input Probe e
p = [In e] -> Probe e -> IO (Out e)
forall e. [In e] -> Probe e -> IO (Out e)
callOrThrow [In e]
input Probe e
p IO (Out e) -> (Out e -> IO (Out e)) -> IO (Out e)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Out e -> IO (Out e)
forall a. NFData a => a -> IO a
evalOrThrow
callOrThrow :: [In e] -> Probe e -> IO (Out e)
callOrThrow :: [In e] -> Probe e -> IO (Out e)
callOrThrow [In e]
input Probe e
p =
Probe e -> [In e] -> IO (Out e)
forall e. Probe e -> [In e] -> IO (Out e)
call Probe e
p [In e]
input IO (Out e) -> (IOError -> IO (Out e)) -> IO (Out e)
forall a. IO a -> (IOError -> IO a) -> IO a
`catchIOError` (AgentException -> IO (Out e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (AgentException -> IO (Out e))
-> (IOError -> AgentException) -> IOError -> IO (Out e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> AgentException
probeRuntimeException (SomeException -> AgentException)
-> (IOError -> SomeException) -> IOError -> AgentException
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOError -> SomeException
forall e. Exception e => e -> SomeException
toException)
evalOrThrow :: (NFData a) => a -> IO a
evalOrThrow :: a -> IO a
evalOrThrow a
x = (a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> a) -> a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
forall a. NFData a => a -> a
force) a
x IO a -> (SomeException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` (AgentException -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (AgentException -> IO a)
-> (SomeException -> AgentException) -> SomeException -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> AgentException
probeRuntimeException)