{-# LANGUAGE FlexibleContexts #-}
module AWS.Lambda.Runtime.Value (
pureRuntime,
pureRuntimeWithContext,
fallibleRuntime,
fallibleRuntimeWithContext,
ioRuntime,
ioRuntimeWithContext,
readerTRuntime,
mRuntime,
mRuntimeWithContext,
) where
import AWS.Lambda.RuntimeClient (RuntimeClientConfig, getRuntimeClientConfig,
getNextData, sendEventError, sendEventSuccess)
import AWS.Lambda.Combinators (withoutContext)
import AWS.Lambda.Context (LambdaContext(..))
import Control.Exception (SomeException, displayException)
import Control.Monad ((<=<), forever)
import Control.Monad.Catch (MonadCatch, try)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Reader (ReaderT, runReaderT)
import Data.Aeson (ToJSON, Value)
import Data.Bifunctor (first)
import Data.Text (unpack)
import System.Environment (setEnv)
runtimeLoop :: (MonadCatch m, MonadIO m, ToJSON result) => RuntimeClientConfig -> (LambdaContext -> Value -> m result) -> m ()
runtimeLoop :: RuntimeClientConfig -> (LambdaContext -> Value -> m result) -> m ()
runtimeLoop RuntimeClientConfig
runtimeClientConfig LambdaContext -> Value -> m result
fn = do
(ByteString
reqIdBS, Value
event, Either String LambdaContext
eCtx) <- IO (ByteString, Value, Either String LambdaContext)
-> m (ByteString, Value, Either String LambdaContext)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ByteString, Value, Either String LambdaContext)
-> m (ByteString, Value, Either String LambdaContext))
-> IO (ByteString, Value, Either String LambdaContext)
-> m (ByteString, Value, Either String LambdaContext)
forall a b. (a -> b) -> a -> b
$ RuntimeClientConfig
-> IO (ByteString, Value, Either String LambdaContext)
getNextData RuntimeClientConfig
runtimeClientConfig
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ (String -> IO ())
-> (LambdaContext -> IO ()) -> Either String LambdaContext -> IO ()
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (IO () -> String -> IO ()
forall a b. a -> b -> a
const (() -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (String -> String -> IO ()
setEnv String
"_X_AMZN_TRACE_ID" (String -> IO ())
-> (LambdaContext -> String) -> LambdaContext -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> String)
-> (LambdaContext -> Text) -> LambdaContext -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LambdaContext -> Text
xRayTraceId) Either String LambdaContext
eCtx
Either SomeException result
caughtResult <- m result -> m (Either SomeException result)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (LambdaContext -> Value -> m result
fn ((String -> LambdaContext)
-> (LambdaContext -> LambdaContext)
-> Either String LambdaContext
-> LambdaContext
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> LambdaContext
forall a. HasCallStack => String -> a
error LambdaContext -> LambdaContext
forall a. a -> a
id Either String LambdaContext
eCtx) Value
event)
let result :: Either String result
result = (SomeException -> String)
-> Either SomeException result -> Either String result
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (SomeException -> String
forall e. Exception e => e -> String
displayException :: SomeException -> String) Either SomeException result
caughtResult
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ case Either String result
result of
Right result
r -> RuntimeClientConfig -> ByteString -> result -> IO ()
forall a.
ToJSON a =>
RuntimeClientConfig -> ByteString -> a -> IO ()
sendEventSuccess RuntimeClientConfig
runtimeClientConfig ByteString
reqIdBS result
r
Left String
e -> RuntimeClientConfig -> ByteString -> String -> IO ()
sendEventError RuntimeClientConfig
runtimeClientConfig ByteString
reqIdBS String
e
mRuntimeWithContext :: (MonadCatch m, MonadIO m, ToJSON result) => (LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext :: (LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext LambdaContext -> Value -> m result
fn = do
RuntimeClientConfig
runtimeClientConfig <- IO RuntimeClientConfig -> m RuntimeClientConfig
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO RuntimeClientConfig
getRuntimeClientConfig
m () -> m ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ RuntimeClientConfig -> (LambdaContext -> Value -> m result) -> m ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
RuntimeClientConfig -> (LambdaContext -> Value -> m result) -> m ()
runtimeLoop RuntimeClientConfig
runtimeClientConfig LambdaContext -> Value -> m result
fn
mRuntime :: (MonadCatch m, MonadIO m, ToJSON result) => (Value -> m result) -> m ()
mRuntime :: (Value -> m result) -> m ()
mRuntime = (LambdaContext -> Value -> m result) -> m ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
(LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext ((LambdaContext -> Value -> m result) -> m ())
-> ((Value -> m result) -> LambdaContext -> Value -> m result)
-> (Value -> m result)
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> m result) -> LambdaContext -> Value -> m result
forall a b. a -> b -> a
withoutContext
readerTRuntime :: ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime :: (Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime Value -> ReaderT LambdaContext IO result
fn = (LambdaContext -> Value -> IO result) -> IO ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
(LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext ((LambdaContext -> Value -> IO result) -> IO ())
-> (LambdaContext -> Value -> IO result) -> IO ()
forall a b. (a -> b) -> a -> b
$ (Value -> LambdaContext -> IO result)
-> LambdaContext -> Value -> IO result
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ReaderT LambdaContext IO result -> LambdaContext -> IO result
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT LambdaContext IO result -> LambdaContext -> IO result)
-> (Value -> ReaderT LambdaContext IO result)
-> Value
-> LambdaContext
-> IO result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> ReaderT LambdaContext IO result
fn)
ioRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> IO (Either String result)) -> IO ()
ioRuntimeWithContext :: (LambdaContext -> Value -> IO (Either String result)) -> IO ()
ioRuntimeWithContext LambdaContext -> Value -> IO (Either String result)
fn = (LambdaContext -> Value -> IO result) -> IO ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
(LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext (\LambdaContext
lc -> (String -> IO result)
-> (result -> IO result) -> Either String result -> IO result
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> IO result
forall a. HasCallStack => String -> a
error result -> IO result
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String result -> IO result)
-> (Value -> IO (Either String result)) -> Value -> IO result
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< IO (Either String result) -> IO (Either String result)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either String result) -> IO (Either String result))
-> (Value -> IO (Either String result))
-> Value
-> IO (Either String result)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LambdaContext -> Value -> IO (Either String result)
fn LambdaContext
lc)
ioRuntime :: ToJSON result =>
(Value -> IO (Either String result)) -> IO ()
ioRuntime :: (Value -> IO (Either String result)) -> IO ()
ioRuntime = (LambdaContext -> Value -> IO (Either String result)) -> IO ()
forall result.
ToJSON result =>
(LambdaContext -> Value -> IO (Either String result)) -> IO ()
ioRuntimeWithContext ((LambdaContext -> Value -> IO (Either String result)) -> IO ())
-> ((Value -> IO (Either String result))
-> LambdaContext -> Value -> IO (Either String result))
-> (Value -> IO (Either String result))
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> IO (Either String result))
-> LambdaContext -> Value -> IO (Either String result)
forall a b. a -> b -> a
withoutContext
fallibleRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> Either String result) -> IO ()
fallibleRuntimeWithContext :: (LambdaContext -> Value -> Either String result) -> IO ()
fallibleRuntimeWithContext = (LambdaContext -> Value -> IO (Either String result)) -> IO ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
(LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext ((LambdaContext -> Value -> IO (Either String result)) -> IO ())
-> ((LambdaContext -> Value -> Either String result)
-> LambdaContext -> Value -> IO (Either String result))
-> (LambdaContext -> Value -> Either String result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Value -> Either String result)
-> Value -> IO (Either String result))
-> (LambdaContext -> Value -> Either String result)
-> LambdaContext
-> Value
-> IO (Either String result)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Either String result -> IO (Either String result))
-> (Value -> Either String result)
-> Value
-> IO (Either String result)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either String result -> IO (Either String result)
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
fallibleRuntime :: ToJSON result =>
(Value -> Either String result) -> IO ()
fallibleRuntime :: (Value -> Either String result) -> IO ()
fallibleRuntime = (LambdaContext -> Value -> Either String result) -> IO ()
forall result.
ToJSON result =>
(LambdaContext -> Value -> Either String result) -> IO ()
fallibleRuntimeWithContext ((LambdaContext -> Value -> Either String result) -> IO ())
-> ((Value -> Either String result)
-> LambdaContext -> Value -> Either String result)
-> (Value -> Either String result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> Either String result)
-> LambdaContext -> Value -> Either String result
forall a b. a -> b -> a
withoutContext
pureRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> result) -> IO ()
pureRuntimeWithContext :: (LambdaContext -> Value -> result) -> IO ()
pureRuntimeWithContext = (LambdaContext -> Value -> IO result) -> IO ()
forall (m :: * -> *) result.
(MonadCatch m, MonadIO m, ToJSON result) =>
(LambdaContext -> Value -> m result) -> m ()
mRuntimeWithContext ((LambdaContext -> Value -> IO result) -> IO ())
-> ((LambdaContext -> Value -> result)
-> LambdaContext -> Value -> IO result)
-> (LambdaContext -> Value -> result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Value -> result) -> Value -> IO result)
-> (LambdaContext -> Value -> result)
-> LambdaContext
-> Value
-> IO result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((result -> IO result) -> (Value -> result) -> Value -> IO result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap result -> IO result
forall (f :: * -> *) a. Applicative f => a -> f a
pure)
pureRuntime :: ToJSON result => (Value -> result) -> IO ()
pureRuntime :: (Value -> result) -> IO ()
pureRuntime = (LambdaContext -> Value -> result) -> IO ()
forall result.
ToJSON result =>
(LambdaContext -> Value -> result) -> IO ()
pureRuntimeWithContext ((LambdaContext -> Value -> result) -> IO ())
-> ((Value -> result) -> LambdaContext -> Value -> result)
-> (Value -> result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> result) -> LambdaContext -> Value -> result
forall a b. a -> b -> a
withoutContext