{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}

{- |
Module: Temporal.Bundle
Description: Utilities to define and reference workflows and activities using records.

Define and reference workflows and activities using records.

The usage of this module is best explained by example. First, define a record type
that contains all of the workflows and activities that you want to define:

@
data EmailWorkflowsB t f = Workflows
 { emailNewUser :: Wear t f (Int -> Workflow ())
 , sendEmail :: Wear t f (String -> Activity () ())
 , emailPasswordReset :: Wear t f (String -> Workflow ())
 } deriving (Generic)

type EmailWorkflows = EmailWorkflowsB Bare Identity
type EmailWorkflowsH = EmailWorkflowsB Covered
@

We define all of our fields using the 'Wear' type, which is a type family
that lets us convert fields from their direct function definitions into
versions that are wrapped in a functor.

Next, we will need some boilerplate instances for this type:

@
instance FunctorB (EmailWorkflowsB Covered)
instance TraversableB (EmailWorkflowsB Covered)
instance ApplicativeB (EmailWorkflowsB Covered)
instance ConstraintsB (EmailWorkflowsB Covered)
instance BareB EmailWorkflowsB
instance Label (EmailWorkflowsB Covered)
@

As an alternative to using 'Generic' and deriving these instances, you can use
'Temporal.Bundle.TH' to generate them for you. With this style, you don't have
to introduce the type parameters manually:

@
import Temporal.Bundle.TH

passthroughBareB [d|
  data EmailWorkflows = Workflows
    { emailNewUser :: Int -> Workflow ()
    , sendEmail :: String -> Activity () ()
    , emailPasswordReset :: String -> Workflow ()
    }
  |]
@

This will generate the same instances as the manual version above,
with the following type synonyms:

@
data EmailWorkflowsB = Workflows {..}
type EmailWorkflows = EmailWorkflowsB Bare Identity
type EmailWorkflowsH = EmailWorkflowsB Covered
@

Now that we have our record type, we can turn it into references and definitions:

Using 'refs', we can use our record type to provide references to our workflows and activities.
References are essentially identifiers that we can use across application / process boundaries
to invoke our workflows and activities with Temporal.

@
wfRefs :: Refs EmailWorkflowsB
wfRefs = refs JSON workflowsImpl
@

Now, we can implement our workflows and activities:

@
workflowsImpl :: EmailWorkflows
workflowsImpl = Workflows
  { emailNewUser = \userId -> provideCallStack $ do
      h <- startActivity
        wfRefs.sendEmail -- <=== Note how we can reference other workflows and activities using the refs we defined above
        (defaultStartActivityOptions $ ScheduleToClose $ TimeSpec 0 0)
        "foo"
      wait h
  , sendEmail = \email -> do
      pure ()
  , emailPasswordReset = \email -> do
      pure ()
  }
@

Lastly, we want a way to register our workflows and activities with the Temporal worker:

@
workerConfigFromRecord = defsToConfig $ defs JSON workflowsImpl
@

This will produce a 'ConfigM' that we can use to register our workflows and activities with the Temporal worker
as part of a larger 'ConfigM' that we pass to 'startWorker'.
-}
module Temporal.Bundle (
  -- * Turning implementations into references and definitions
  refs,
  Refs,
  Ref,
  defs,
  Defs,
  Def,
  collectTemporalDefinitions,
  Impl,
  inWorkflowProxies,
  InWorkflowProxies,
  InWorkflowProxyOptions,
  RefStartOptions,
  UseAsInWorkflowProxy (..),
  provideDefaultOptions,
  FieldToStartOptionDefaults (..),
  RefStartOptionsType,

  -- * Worker management
  withTaskQueues,
  linkTaskQueues,
  startTaskQueues,
  shutdownTaskQueues,
  WorkerConfigs,
  Workers,

  -- * Other utilities
  coerceRec,
  Equate,
  ProxySync (..),
  ProxyAsync (..),

  -- * Reexports

  -- * Constraints
  CanUseAsRefs,
  CanUseAsDefs,
  RefFromFunction,
  RefFromFunction' (..),
  DefFromFunction,
  DefFromFunction' (..),
  WorkflowRef (..),
  ActivityRef (..),
  InnerActivityResult,
  ApplyDef,
  ApplyRef,
) where

import Control.Monad
import Control.Monad.Catch
import Control.Monad.Logger
import Control.Monad.Reader
import Data.EvalRecord (
  AllRec,
  ApplicativeRec,
  ConstraintsRec,
  TraversableRec,
 )
import qualified Data.EvalRecord as Rec
import Data.Kind
import Data.Proxy
import qualified Data.Text as Text
import Fcf
import GHC.TypeLits
import RequireCallStack
import Temporal.Activity
import Temporal.Activity.Definition
import Temporal.Common.Async
import Temporal.Core.Client
import Temporal.Payload
import Temporal.Worker
import Temporal.Workflow
import Temporal.Workflow.Internal.Monad
import Temporal.Workflow.Types
import UnliftIO
import Unsafe.Coerce


type family ApplyRef (original :: Type) (f :: Type) where
  ApplyRef original (Workflow result) = KnownWorkflow (ArgsOf original) result
  ApplyRef original (Activity _ result) = KnownActivity (ArgsOf original) result
  ApplyRef original (_ -> b) = ApplyRef original b
  ApplyRef _ a = TypeError ('Text "Expected a Workflow or Activity, but got " ':<>: 'ShowType a)


{- | A reference to a workflow or activity.

Depending on whether the result monad is 'Workflow' or 'Activity',
the 'Eval' instance will resolve to either a 'KnownWorkflow' or 'KnownActivity'.
-}
data Ref :: Type -> Exp Type


type instance Eval (Ref f) = ApplyRef f f


type family ApplyDef (f :: Type) where
  ApplyDef (Workflow _) = WorkflowDefinition
  ApplyDef (Activity env _) = ActivityDefinition env
  ApplyDef (_ -> b) = ApplyDef b
  ApplyDef a = TypeError ('Text "Expected a Workflow or Activity, but got " ':<>: 'ShowType a)


data Def :: Type -> Type -> Exp Type


type instance Eval (Def _ f) = ApplyDef f


type family InnerActivityResult (f :: Type) where
  InnerActivityResult (Activity _ result) = result
  InnerActivityResult (_ -> b) = InnerActivityResult b
  InnerActivityResult a = TypeError ('Text "Expected an Activity, but got " ':<>: 'ShowType a)


class RefFromFunction' codec (f :: Type) original where
  refFromFunction :: Proxy f -> codec -> String -> Proxy original -> Ref @@ original


instance
  ( FunctionSupportsCodec' Workflow codec original
  , Ref @@ original ~ KnownWorkflow (ArgsOf original) (ResultOf Workflow original)
  )
  => RefFromFunction' codec (Workflow result) original
  where
  refFromFunction :: Proxy (Workflow result)
-> codec -> String -> Proxy original -> Ref @@ original
refFromFunction Proxy (Workflow result)
_ codec
codec String
name Proxy original
_ = codec
-> Text
-> KnownWorkflow (ArgsOf original) (ResultOf Workflow original)
forall (args :: [*]) result codec.
FunctionSupportsCodec codec args result =>
codec -> Text -> KnownWorkflow args result
KnownWorkflow codec
codec (Text
 -> KnownWorkflow (ArgsOf original) (ResultOf Workflow original))
-> Text
-> KnownWorkflow (ArgsOf original) (ResultOf Workflow original)
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
name


instance
  ( FunctionSupportsCodec' (Activity env) codec original
  , Ref @@ original ~ KnownActivity (ArgsOf original) (ResultOf (Activity env) original)
  )
  => RefFromFunction' codec (Activity env result) original
  where
  refFromFunction :: Proxy (Activity env result)
-> codec -> String -> Proxy original -> Ref @@ original
refFromFunction Proxy (Activity env result)
_ codec
codec String
name Proxy original
_ = codec
-> Text
-> KnownActivity
     (ArgsOf original) (ResultOf (Activity env) original)
forall (args :: [*]) result codec.
FunctionSupportsCodec codec args result =>
codec -> Text -> KnownActivity args result
KnownActivity codec
codec (Text
 -> KnownActivity
      (ArgsOf original) (ResultOf (Activity env) original))
-> Text
-> KnownActivity
     (ArgsOf original) (ResultOf (Activity env) original)
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
name


instance RefFromFunction' codec b original => RefFromFunction' codec (a -> b) original where
  refFromFunction :: Proxy (a -> b)
-> codec -> String -> Proxy original -> Ref @@ original
refFromFunction Proxy (a -> b)
_ = Proxy b -> codec -> String -> Proxy original -> Ref @@ original
forall codec f original.
RefFromFunction' codec f original =>
Proxy f -> codec -> String -> Proxy original -> Ref @@ original
refFromFunction (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @b)


class RefFromFunction' codec f f => RefFromFunction codec f


instance RefFromFunction' codec f f => RefFromFunction codec f


class DefFromFunction' codec env (f :: Type) (original :: Type) where
  defFromFunction :: RequireCallStack => Proxy f -> codec -> String -> original -> Def env @@ original


class DefFromFunction' codec env f f => DefFromFunction codec env f


instance DefFromFunction' codec env f f => DefFromFunction codec env f


instance
  ( FunctionSupportsCodec' Workflow codec original
  , Def env @@ original ~ WorkflowDefinition
  )
  => DefFromFunction' codec env (Workflow result) original
  where
  defFromFunction :: RequireCallStack =>
Proxy (Workflow result)
-> codec -> String -> original -> Def env @@ original
defFromFunction Proxy (Workflow result)
_ codec
codec String
name original
f = Text
-> (Vector Payload -> IO (Either String (Workflow Payload)))
-> WorkflowDefinition
WorkflowDefinition (String -> Text
Text.pack String
name) ((Vector Payload -> IO (Either String (Workflow Payload)))
 -> WorkflowDefinition)
-> (Vector Payload -> IO (Either String (Workflow Payload)))
-> WorkflowDefinition
forall a b. (a -> b) -> a -> b
$ \Vector Payload
payloads -> do
    eWf <-
      codec
-> Proxy (ArgsOf original)
-> Proxy (Workflow (ResultOf Workflow original))
-> (ArgsOf original :->: Workflow (ResultOf Workflow original))
-> Vector Payload
-> IO (Either String (Workflow (ResultOf Workflow original)))
forall result.
codec
-> Proxy (ArgsOf original)
-> Proxy result
-> (ArgsOf original :->: result)
-> Vector Payload
-> IO (Either String result)
forall codec (args :: [*]) result.
ApplyPayloads codec args =>
codec
-> Proxy args
-> Proxy result
-> (args :->: result)
-> Vector Payload
-> IO (Either String result)
applyPayloads
        codec
codec
        (forall (t :: [*]). Proxy t
forall {k} (t :: k). Proxy t
Proxy @(ArgsOf original))
        (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Workflow (ResultOf Workflow original)))
        original
ArgsOf original :->: Workflow (ResultOf Workflow original)
f
        Vector Payload
payloads
    pure $ fmap (\Workflow (ResultOf Workflow original)
wf -> Workflow (ResultOf Workflow original)
wf Workflow (ResultOf Workflow original)
-> (ResultOf Workflow original -> Workflow Payload)
-> Workflow Payload
forall a b. Workflow a -> (a -> Workflow b) -> Workflow b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ResultOf Workflow original
result -> InstanceM Payload -> Workflow Payload
forall a. RequireCallStack => InstanceM a -> Workflow a
ilift (IO Payload -> InstanceM Payload
forall a. IO a -> InstanceM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Payload -> InstanceM Payload)
-> IO Payload -> InstanceM Payload
forall a b. (a -> b) -> a -> b
$ codec -> ResultOf Workflow original -> IO Payload
forall fmt a. Codec fmt a => fmt -> a -> IO Payload
encode codec
codec ResultOf Workflow original
result)) eWf


instance
  ( FunctionSupportsCodec' (Activity env) codec original
  , Def env @@ original ~ ActivityDefinition env
  )
  => DefFromFunction' codec env (Activity env result) original
  where
  defFromFunction :: RequireCallStack =>
Proxy (Activity env result)
-> codec -> String -> original -> Def env @@ original
defFromFunction Proxy (Activity env result)
_ codec
codec String
name original
f =
    Text
-> (ActivityEnv env
    -> ExecuteActivityInput -> IO (Either String Payload))
-> ActivityDefinition env
forall env.
Text
-> (ActivityEnv env
    -> ExecuteActivityInput -> IO (Either String Payload))
-> ActivityDefinition env
ActivityDefinition
      (String -> Text
Text.pack String
name)
      ( \ActivityEnv env
actEnv ExecuteActivityInput
input -> do
          eAct <-
            codec
-> Proxy (ArgsOf original)
-> Proxy (Activity env (ResultOf (Activity env) original))
-> (ArgsOf original
    :->: Activity env (ResultOf (Activity env) original))
-> Vector Payload
-> IO
     (Either String (Activity env (ResultOf (Activity env) original)))
forall result.
codec
-> Proxy (ArgsOf original)
-> Proxy result
-> (ArgsOf original :->: result)
-> Vector Payload
-> IO (Either String result)
forall codec (args :: [*]) result.
ApplyPayloads codec args =>
codec
-> Proxy args
-> Proxy result
-> (args :->: result)
-> Vector Payload
-> IO (Either String result)
applyPayloads
              codec
codec
              (forall (t :: [*]). Proxy t
forall {k} (t :: k). Proxy t
Proxy @(ArgsOf original))
              (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Activity env (ResultOf (Activity env) original)))
              original
ArgsOf original
:->: Activity env (ResultOf (Activity env) original)
f
              ExecuteActivityInput
input.activityArgs
          traverse (runActivity actEnv >=> encode codec) eAct
      )


instance DefFromFunction' codec env b original => DefFromFunction' codec env (a -> b) original where
  defFromFunction :: RequireCallStack =>
Proxy (a -> b)
-> codec -> String -> original -> Def env @@ original
defFromFunction Proxy (a -> b)
_ = forall codec env f original.
(DefFromFunction' codec env f original, RequireCallStack) =>
Proxy f -> codec -> String -> original -> Def env @@ original
defFromFunction @codec @env (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @b)


-- | A bare record type that supplies the actual implementation of workflows and activities.
type Impl f = f Pure


-- | References to workflows and activities that can be used at invokation callsites.
type Refs f = f Ref


-- | A wrapped version of the implementations that carries information needed to register workflows and activities with the Temporal worker.
type Defs env f = f (Def env)


type CanUseAsRefs f codec =
  ( ConstraintsRec f
  , Rec.WitnessFieldTypes f
  , AllRec (RefFromFunction codec) f
  , ApplicativeRec f
  )


{- | Produce a record of references to workflows and activities from a record of implementations.

The fields in the records produced by this function can be used to invoke the workflows and activities
via the Temporal client or within Temporal workflows.
-}
refs
  :: forall r codec
   . ( CanUseAsRefs r codec
     )
  => codec
  -> Refs r
refs :: forall (r :: (* -> * -> *) -> *) codec.
CanUseAsRefs r codec =>
codec -> Refs r
refs codec
codec = r Ref
result
  where
    ns :: String
    ns :: String
ns = Proxy r -> String
forall (rec :: (* -> * -> *) -> *).
WitnessFieldTypes rec =>
Proxy rec -> String
Rec.typeName (forall {k} (t :: k). Proxy t
forall (t :: (* -> * -> *) -> *). Proxy t
Proxy @r)

    defLabels :: r (ConstFn String)
    defLabels :: r (ConstFn String)
defLabels = (forall a. Metadata a -> ConstFn String @@ a) -> r (ConstFn String)
forall (f :: * -> * -> *). (forall a. Metadata a -> f @@ a) -> r f
forall (rec :: (* -> * -> *) -> *) (f :: * -> * -> *).
ApplicativeRec rec =>
(forall a. Metadata a -> f @@ a) -> rec f
Rec.pure (\Metadata a
meta -> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String
ns, String
".", Metadata a -> String
forall {k} (a :: k). Metadata a -> String
Rec.name Metadata a
meta])

    convertToKnownWorkflow :: forall wf. RefFromFunction codec wf => Rec.Metadata wf -> String -> Ref @@ wf
    convertToKnownWorkflow :: forall wf.
RefFromFunction codec wf =>
Metadata wf -> String -> Ref @@ wf
convertToKnownWorkflow Metadata wf
_ String
n = Proxy wf -> codec -> String -> Proxy wf -> Ref @@ wf
forall codec f original.
RefFromFunction' codec f original =>
Proxy f -> codec -> String -> Proxy original -> Ref @@ original
refFromFunction (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @wf) codec
codec String
n (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @wf)

    result :: r Ref
    result :: r Ref
result = forall (c :: * -> Constraint) (b :: (* -> * -> *) -> *)
       (f :: * -> * -> *) (g :: * -> * -> *).
(AllRec c b, ConstraintsRec b) =>
(forall a. c a => Metadata a -> (f @@ a) -> g @@ a) -> b f -> b g
Rec.mapC @(RefFromFunction codec) Metadata a -> String -> Ref @@ a
Metadata a -> Eval (ConstFn String a) -> Ref @@ a
forall wf.
RefFromFunction codec wf =>
Metadata wf -> String -> Ref @@ wf
forall a.
RefFromFunction codec a =>
Metadata a -> (ConstFn String @@ a) -> Ref @@ a
convertToKnownWorkflow r (ConstFn String)
defLabels


{- | Constraints needed to turn a record of implementations into a record of definitions.

That is, all of the fields (Workflows, Activities) in the record support the supplied codec,
and the activities have an environment of type @env@.
-}
type CanUseAsDefs f codec env =
  ( ConstraintsRec f
  , Rec.WitnessFieldTypes f
  , AllRec (DefFromFunction codec env) f
  , ApplicativeRec f
  )


-- | Produce a record of definitions from a record of implementations, using the supplied codec.
defs
  :: forall f codec env
   . ( CanUseAsDefs f codec env
     )
  => codec
  -> Impl f
  -> Defs env f
defs :: forall (f :: (* -> * -> *) -> *) codec env.
CanUseAsDefs f codec env =>
codec -> Impl f -> Defs env f
defs codec
codec Impl f
wfrec = f (Def env)
result
  where
    ns :: String
    ns :: String
ns = Proxy f -> String
forall (rec :: (* -> * -> *) -> *).
WitnessFieldTypes rec =>
Proxy rec -> String
Rec.typeName (forall {k} (t :: k). Proxy t
forall (t :: (* -> * -> *) -> *). Proxy t
Proxy @f)

    defLabels :: f (ConstFn String)
    defLabels :: f (ConstFn String)
defLabels = (forall a. Metadata a -> ConstFn String @@ a) -> f (ConstFn String)
forall (f :: * -> * -> *). (forall a. Metadata a -> f @@ a) -> f f
forall (rec :: (* -> * -> *) -> *) (f :: * -> * -> *).
ApplicativeRec rec =>
(forall a. Metadata a -> f @@ a) -> rec f
Rec.pure (\Metadata a
meta -> [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String
ns, String
".", Metadata a -> String
forall {k} (a :: k). Metadata a -> String
Rec.name Metadata a
meta])

    labeledFields :: f (Rec.Tuple2 (ConstFn String) Pure)
    labeledFields :: f (Tuple2 (ConstFn String) Pure)
labeledFields = (forall a.
 Metadata a
 -> (ConstFn String @@ a)
 -> (Pure @@ a)
 -> Tuple2 (ConstFn String) Pure @@ a)
-> f (ConstFn String) -> Impl f -> f (Tuple2 (ConstFn String) Pure)
forall (rec :: (* -> * -> *) -> *) (f :: * -> * -> *)
       (g :: * -> * -> *) (h :: * -> * -> *).
ApplicativeRec rec =>
(forall a. Metadata a -> (f @@ a) -> (g @@ a) -> h @@ a)
-> rec f -> rec g -> rec h
Rec.zipWith (\Metadata a
_ ConstFn String @@ a
label Pure @@ a
f -> (String
ConstFn String @@ a
label, a
Pure @@ a
f)) f (ConstFn String)
defLabels Impl f
wfrec

    convertToWorkflowDefinition :: forall wf. (DefFromFunction codec env wf) => Rec.Metadata wf -> (String, wf) -> Def env @@ wf
    convertToWorkflowDefinition :: forall wf.
DefFromFunction codec env wf =>
Metadata wf -> (String, wf) -> Def env @@ wf
convertToWorkflowDefinition Metadata wf
_ (String
n, wf
f) = (RequireCallStackImpl => Def env @@ wf) -> Def env @@ wf
forall r. (RequireCallStackImpl => r) -> r
provideCallStack ((RequireCallStackImpl => Def env @@ wf) -> Def env @@ wf)
-> (RequireCallStackImpl => Def env @@ wf) -> Def env @@ wf
forall a b. (a -> b) -> a -> b
$ forall codec env f original.
(DefFromFunction' codec env f original, RequireCallStack) =>
Proxy f -> codec -> String -> original -> Def env @@ original
defFromFunction @codec @env (wf -> Proxy wf
forall a. a -> Proxy a
forall (f :: * -> *) a. Applicative f => a -> f a
pure wf
f) codec
codec String
n wf
f

    result :: f (Def env)
    result :: f (Def env)
result = forall (c :: * -> Constraint) (b :: (* -> * -> *) -> *)
       (f :: * -> * -> *) (g :: * -> * -> *).
(AllRec c b, ConstraintsRec b) =>
(forall a. c a => Metadata a -> (f @@ a) -> g @@ a) -> b f -> b g
Rec.mapC @(DefFromFunction codec env) Metadata a -> (String, a) -> Def env @@ a
Metadata a -> Eval (Tuple2 (ConstFn String) Pure a) -> Def env @@ a
forall wf.
DefFromFunction codec env wf =>
Metadata wf -> (String, wf) -> Def env @@ wf
forall a.
DefFromFunction codec env a =>
Metadata a -> (Tuple2 (ConstFn String) Pure @@ a) -> Def env @@ a
convertToWorkflowDefinition f (Tuple2 (ConstFn String) Pure)
labeledFields


-- | Convert a record of 'Def' values into a worker and  that you can pass to 'startWorker'.
collectTemporalDefinitions :: forall rec actEnv f. (TraversableRec rec, ConstraintsRec rec, Rec.AllRecF (ToDefinitions actEnv) f rec) => rec f -> Definitions actEnv
collectTemporalDefinitions :: forall (rec :: (* -> * -> *) -> *) actEnv (f :: * -> * -> *).
(TraversableRec rec, ConstraintsRec rec,
 AllRecF (ToDefinitions actEnv) f rec) =>
rec f -> Definitions actEnv
collectTemporalDefinitions = forall (c :: * -> Constraint) (b :: (* -> * -> *) -> *) m
       (f :: * -> * -> *).
(TraversableRec b, ConstraintsRec b, AllRec c b, Monoid m) =>
(forall a. c a => Metadata a -> (f @@ a) -> m) -> b f -> m
Rec.foldMapC @(Rec.ClassF (ToDefinitions actEnv) f) Metadata a -> (f @@ a) -> Definitions actEnv
forall a.
ClassF (ToDefinitions actEnv) f a =>
Metadata a -> (f @@ a) -> Definitions actEnv
forall a.
ToDefinitions actEnv (f @@ a) =>
Metadata a -> (f @@ a) -> Definitions actEnv
mkConf
  where
    mkConf :: forall a. ToDefinitions actEnv (f @@ a) => Rec.Metadata a -> f @@ a -> Definitions actEnv
    mkConf :: forall a.
ToDefinitions actEnv (f @@ a) =>
Metadata a -> (f @@ a) -> Definitions actEnv
mkConf Metadata a
_ = (f @@ a) -> Definitions actEnv
forall env f. ToDefinitions env f => f -> Definitions env
toDefinitions


type family RefStartOptionsType (f :: Type) :: Type where
  RefStartOptionsType (Activity _ _) = StartActivityOptions
  RefStartOptionsType (_ -> b) = RefStartOptionsType b
  RefStartOptionsType (Workflow _) = StartChildWorkflowOptions
  RefStartOptionsType (KnownWorkflow _ _) = StartChildWorkflowOptions
  RefStartOptionsType (KnownActivity _ _) = StartActivityOptions


class FieldToStartOptionDefaults f where
  refStartOptionsDefaults
    :: Proxy f
    -> StartActivityOptions
    -> StartChildWorkflowOptions
    -> RefStartOptionsType f


instance FieldToStartOptionDefaults b => FieldToStartOptionDefaults (a -> b) where
  refStartOptionsDefaults :: Proxy (a -> b)
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType (a -> b)
refStartOptionsDefaults Proxy (a -> b)
_ = Proxy b
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType b
forall f.
FieldToStartOptionDefaults f =>
Proxy f
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType f
refStartOptionsDefaults (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @b)


instance FieldToStartOptionDefaults (Activity env result) where
  refStartOptionsDefaults :: Proxy (Activity env result)
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType (Activity env result)
refStartOptionsDefaults Proxy (Activity env result)
_ StartActivityOptions
opts StartChildWorkflowOptions
_ = StartActivityOptions
RefStartOptionsType (Activity env result)
opts


instance FieldToStartOptionDefaults (KnownActivity args res) where
  refStartOptionsDefaults :: Proxy (KnownActivity args res)
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType (KnownActivity args res)
refStartOptionsDefaults Proxy (KnownActivity args res)
_ StartActivityOptions
opts StartChildWorkflowOptions
_ = StartActivityOptions
RefStartOptionsType (KnownActivity args res)
opts


instance FieldToStartOptionDefaults (Workflow a) where
  refStartOptionsDefaults :: Proxy (Workflow a)
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType (Workflow a)
refStartOptionsDefaults Proxy (Workflow a)
_ StartActivityOptions
_ StartChildWorkflowOptions
opts = StartChildWorkflowOptions
RefStartOptionsType (Workflow a)
opts


instance FieldToStartOptionDefaults (KnownWorkflow args res) where
  refStartOptionsDefaults :: Proxy (KnownWorkflow args res)
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType (KnownWorkflow args res)
refStartOptionsDefaults Proxy (KnownWorkflow args res)
_ StartActivityOptions
_ StartChildWorkflowOptions
opts = StartChildWorkflowOptions
RefStartOptionsType (KnownWorkflow args res)
opts


data RefStartOptions :: Type -> Exp Type


type instance Eval (RefStartOptions f) = RefStartOptionsType f


{- | Define a record that provides the same default options for all activities in the a record.

This is useful when you want to provide the same default options for all activities in a record.
For example, you might want to provide a default timeout or non-retryable error type list for all activities.
-}
provideDefaultOptions
  :: forall rec
   . (ApplicativeRec rec, ConstraintsRec rec, AllRec FieldToStartOptionDefaults rec)
  => StartActivityOptions
  -> StartChildWorkflowOptions
  -> rec RefStartOptions
provideDefaultOptions :: forall (rec :: (* -> * -> *) -> *).
(ApplicativeRec rec, ConstraintsRec rec,
 AllRec FieldToStartOptionDefaults rec) =>
StartActivityOptions
-> StartChildWorkflowOptions -> rec RefStartOptions
provideDefaultOptions StartActivityOptions
act StartChildWorkflowOptions
wf =
  forall (c :: * -> Constraint) (b :: (* -> * -> *) -> *)
       (f :: * -> * -> *) (g :: * -> * -> *).
(AllRec c b, ConstraintsRec b) =>
(forall a. c a => Metadata a -> (f @@ a) -> g @@ a) -> b f -> b g
Rec.mapC
    @FieldToStartOptionDefaults
    Metadata a -> () -> RefStartOptions @@ a
Metadata a -> Eval (ConstFn () a) -> RefStartOptions @@ a
forall a.
FieldToStartOptionDefaults a =>
Metadata a -> () -> RefStartOptions @@ a
forall a.
FieldToStartOptionDefaults a =>
Metadata a -> (ConstFn () @@ a) -> RefStartOptions @@ a
mkDefaults
    rec (ConstFn ())
emptyBase
  where
    mkDefaults :: forall a. FieldToStartOptionDefaults a => Rec.Metadata a -> () -> RefStartOptions @@ a
    mkDefaults :: forall a.
FieldToStartOptionDefaults a =>
Metadata a -> () -> RefStartOptions @@ a
mkDefaults Metadata a
meta ()
_ = Proxy a
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType a
forall f.
FieldToStartOptionDefaults f =>
Proxy f
-> StartActivityOptions
-> StartChildWorkflowOptions
-> RefStartOptionsType f
refStartOptionsDefaults (Metadata a -> Proxy a
forall {k} (a :: k). Metadata a -> Proxy a
proxyFromMeta Metadata a
meta) StartActivityOptions
act StartChildWorkflowOptions
wf
    proxyFromMeta :: forall a. Rec.Metadata a -> Proxy a
    proxyFromMeta :: forall {k} (a :: k). Metadata a -> Proxy a
proxyFromMeta = Proxy a -> Metadata a -> Proxy a
forall a b. a -> b -> a
const Proxy a
forall {k} (t :: k). Proxy t
Proxy
    emptyBase :: rec (ConstFn ())
    emptyBase :: rec (ConstFn ())
emptyBase = (forall a. Metadata a -> ConstFn () @@ a) -> rec (ConstFn ())
forall (f :: * -> * -> *).
(forall a. Metadata a -> f @@ a) -> rec f
forall (rec :: (* -> * -> *) -> *) (f :: * -> * -> *).
ApplicativeRec rec =>
(forall a. Metadata a -> f @@ a) -> rec f
Rec.pure ((forall a. Metadata a -> ConstFn () @@ a) -> rec (ConstFn ()))
-> (forall a. Metadata a -> ConstFn () @@ a) -> rec (ConstFn ())
forall a b. (a -> b) -> a -> b
$ () -> Metadata a -> ()
forall a b. a -> b -> a
const ()


data InWorkflowProxies :: Type -> Type -> Exp Type


type instance Eval (InWorkflowProxies ProxySync (KnownWorkflow args res)) = args :->: Workflow res


type instance Eval (InWorkflowProxies ProxyAsync (KnownWorkflow args res)) = args :->: Workflow (ChildWorkflowHandle res)


type instance Eval (InWorkflowProxies ProxySync (KnownActivity args res)) = args :->: Workflow res


type instance Eval (InWorkflowProxies ProxyAsync (KnownActivity args res)) = args :->: Workflow (Task res)


class UseAsInWorkflowProxy synchronicity ref where
  useAsInWorkflowProxy
    :: RequireCallStack
    => synchronicity
    -> ref
    -> RefStartOptions @@ ref
    -> InWorkflowProxies synchronicity @@ ref


instance VarArgs args => UseAsInWorkflowProxy ProxySync (KnownActivity args res) where
  useAsInWorkflowProxy :: RequireCallStack =>
ProxySync
-> KnownActivity args res
-> (RefStartOptions @@ KnownActivity args res)
-> InWorkflowProxies ProxySync @@ KnownActivity args res
useAsInWorkflowProxy ProxySync
_ = KnownActivity args res
-> (RefStartOptions @@ KnownActivity args res)
-> InWorkflowProxies ProxySync @@ KnownActivity args res
KnownActivity args res
-> StartActivityOptions
-> ActivityArgs (KnownActivity args res)
   :->: Workflow (ActivityResult (KnownActivity args res))
forall activity.
(RequireCallStack, ActivityRef activity) =>
activity
-> StartActivityOptions
-> ActivityArgs activity :->: Workflow (ActivityResult activity)
executeActivity


instance VarArgs args => UseAsInWorkflowProxy ProxyAsync (KnownActivity args res) where
  useAsInWorkflowProxy :: RequireCallStack =>
ProxyAsync
-> KnownActivity args res
-> (RefStartOptions @@ KnownActivity args res)
-> InWorkflowProxies ProxyAsync @@ KnownActivity args res
useAsInWorkflowProxy ProxyAsync
_ = KnownActivity args res
-> (RefStartOptions @@ KnownActivity args res)
-> InWorkflowProxies ProxyAsync @@ KnownActivity args res
KnownActivity args res
-> StartActivityOptions
-> ActivityArgs (KnownActivity args res)
   :->: Workflow (Task (ActivityResult (KnownActivity args res)))
forall activity.
(RequireCallStack, ActivityRef activity) =>
activity
-> StartActivityOptions
-> ActivityArgs activity
   :->: Workflow (Task (ActivityResult activity))
startActivity


instance UseAsInWorkflowProxy ProxySync (KnownWorkflow args res) where
  useAsInWorkflowProxy :: RequireCallStack =>
ProxySync
-> KnownWorkflow args res
-> (RefStartOptions @@ KnownWorkflow args res)
-> InWorkflowProxies ProxySync @@ KnownWorkflow args res
useAsInWorkflowProxy ProxySync
_ = KnownWorkflow args res
-> (RefStartOptions @@ KnownWorkflow args res)
-> InWorkflowProxies ProxySync @@ KnownWorkflow args res
KnownWorkflow args res
-> StartChildWorkflowOptions
-> WorkflowArgs (KnownWorkflow args res)
   :->: Workflow (WorkflowResult (KnownWorkflow args res))
forall wf.
(RequireCallStack, WorkflowRef wf) =>
wf
-> StartChildWorkflowOptions
-> WorkflowArgs wf :->: Workflow (WorkflowResult wf)
executeChildWorkflow


instance UseAsInWorkflowProxy ProxyAsync (KnownWorkflow args res) where
  useAsInWorkflowProxy :: RequireCallStack =>
ProxyAsync
-> KnownWorkflow args res
-> (RefStartOptions @@ KnownWorkflow args res)
-> InWorkflowProxies ProxyAsync @@ KnownWorkflow args res
useAsInWorkflowProxy ProxyAsync
_ = KnownWorkflow args res
-> (RefStartOptions @@ KnownWorkflow args res)
-> InWorkflowProxies ProxyAsync @@ KnownWorkflow args res
KnownWorkflow args res
-> StartChildWorkflowOptions
-> WorkflowArgs (KnownWorkflow args res)
   :->: Workflow
          (ChildWorkflowHandle (WorkflowResult (KnownWorkflow args res)))
forall wf.
(RequireCallStack, WorkflowRef wf) =>
wf
-> StartChildWorkflowOptions
-> WorkflowArgs wf
   :->: Workflow (ChildWorkflowHandle (WorkflowResult wf))
startChildWorkflow


data ProxySync = ProxySync


data ProxyAsync = ProxyAsync


class (c @@ a ~ d @@ a) => Equate c d a


instance (c @@ a ~ d @@ a) => Equate c d a


coerceRec :: Rec.AllRec (Equate c d) rec => rec c -> rec d
coerceRec :: forall (c :: * -> * -> *) (d :: * -> * -> *)
       (rec :: (* -> * -> *) -> *).
AllRec (Equate c d) rec =>
rec c -> rec d
coerceRec = rec c -> rec d
forall a b. a -> b
unsafeCoerce


type InWorkflowProxyOptions = RefStartOptions <=< Ref


{- | Combine a record of references with a record of default options to give a record of
functions that can be used to start activities and workflows. This is just a convenience
function that makes it so that you don't have to call 'executeActivity' or 'executeChildWorkflow'
directly as often.
-}
inWorkflowProxies
  :: forall synchronicity rec
   . (RequireCallStack, ConstraintsRec rec, Rec.AllRec (Rec.ClassF (UseAsInWorkflowProxy synchronicity) Ref) rec, ApplicativeRec rec)
  => synchronicity
  -> rec (RefStartOptions <=< Ref)
  -> rec Ref
  -> rec (InWorkflowProxies synchronicity <=< Ref)
inWorkflowProxies :: forall synchronicity (rec :: (* -> * -> *) -> *).
(RequireCallStack, ConstraintsRec rec,
 AllRec (ClassF (UseAsInWorkflowProxy synchronicity) Ref) rec,
 ApplicativeRec rec) =>
synchronicity
-> rec (RefStartOptions <=< Ref)
-> rec Ref
-> rec (InWorkflowProxies synchronicity <=< Ref)
inWorkflowProxies synchronicity
s = forall (c :: * -> Constraint) (b :: (* -> * -> *) -> *)
       (f :: * -> * -> *) (g :: * -> * -> *) (h :: * -> * -> *).
(AllRec c b, ConstraintsRec b, ApplicativeRec b) =>
(forall a. c a => Metadata a -> (f @@ a) -> (g @@ a) -> h @@ a)
-> b f -> b g -> b h
Rec.zipWithC @(Rec.ClassF (UseAsInWorkflowProxy synchronicity) Ref) Metadata a
-> ((RefStartOptions <=< Ref) @@ a)
-> (Ref @@ a)
-> (InWorkflowProxies synchronicity <=< Ref) @@ a
forall a.
ClassF (UseAsInWorkflowProxy synchronicity) Ref a =>
Metadata a
-> ((RefStartOptions <=< Ref) @@ a)
-> (Ref @@ a)
-> (InWorkflowProxies synchronicity <=< Ref) @@ a
forall a.
UseAsInWorkflowProxy synchronicity (Ref @@ a) =>
Metadata a
-> ((RefStartOptions <=< Ref) @@ a)
-> (Ref @@ a)
-> (InWorkflowProxies synchronicity <=< Ref) @@ a
convertToProxies
  where
    convertToProxies
      :: forall a
       . (UseAsInWorkflowProxy synchronicity (Ref @@ a))
      => Rec.Metadata a
      -> InWorkflowProxyOptions @@ a
      -> Ref @@ a
      -> (InWorkflowProxies synchronicity <=< Ref) @@ a
    convertToProxies :: forall a.
UseAsInWorkflowProxy synchronicity (Ref @@ a) =>
Metadata a
-> ((RefStartOptions <=< Ref) @@ a)
-> (Ref @@ a)
-> (InWorkflowProxies synchronicity <=< Ref) @@ a
convertToProxies Metadata a
_ (RefStartOptions <=< Ref) @@ a
opt Ref @@ a
ref = synchronicity
-> ApplyRef a a
-> (RefStartOptions @@ ApplyRef a a)
-> InWorkflowProxies synchronicity @@ ApplyRef a a
forall synchronicity ref.
(UseAsInWorkflowProxy synchronicity ref, RequireCallStack) =>
synchronicity
-> ref
-> (RefStartOptions @@ ref)
-> InWorkflowProxies synchronicity @@ ref
useAsInWorkflowProxy synchronicity
s Ref @@ a
ApplyRef a a
ref (RefStartOptions <=< Ref) @@ a
RefStartOptions @@ ApplyRef a a
opt


type Workers env rec = rec (ConstFn (Worker env))


type WorkerConfigs env rec = rec (ConstFn (WorkerConfig env))


{- | Start a Temporal worker for each task queue specified in the MercuryTaskQueues record.

This function starts each worker concurrently, waits for them to initialize, and then returns
a worker for each task queue.
-}
startTaskQueues :: forall rec m env. (TraversableRec rec, MonadUnliftIO m, MonadCatch m) => Client -> WorkerConfigs env rec -> m (Workers env rec)
startTaskQueues :: forall (rec :: (* -> * -> *) -> *) (m :: * -> *) env.
(TraversableRec rec, MonadUnliftIO m, MonadCatch m) =>
Client -> WorkerConfigs env rec -> m (Workers env rec)
startTaskQueues Client
client WorkerConfigs env rec
conf = WorkerConfigs env rec -> m (rec (ConstFn (Async (Worker env))))
startWorkers WorkerConfigs env rec
conf m (rec (ConstFn (Async (Worker env))))
-> (rec (ConstFn (Async (Worker env))) -> m (Workers env rec))
-> m (Workers env rec)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= rec (ConstFn (Async (Worker env))) -> m (Workers env rec)
awaitWorkersStart
  where
    startWorkers :: rec (ConstFn (WorkerConfig env)) -> m (rec (ConstFn (Async (Worker env))))
    startWorkers :: WorkerConfigs env rec -> m (rec (ConstFn (Async (Worker env))))
startWorkers = (forall a.
 Metadata a
 -> (ConstFn (WorkerConfig env) @@ a)
 -> m (ConstFn (Async (Worker env)) @@ a))
-> WorkerConfigs env rec -> m (rec (ConstFn (Async (Worker env))))
forall (e :: * -> *) (f :: * -> * -> *) (g :: * -> * -> *).
Applicative e =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
forall (rec :: (* -> * -> *) -> *) (e :: * -> *) (f :: * -> * -> *)
       (g :: * -> * -> *).
(TraversableRec rec, Applicative e) =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
Rec.traverse ((forall a.
  Metadata a
  -> (ConstFn (WorkerConfig env) @@ a)
  -> m (ConstFn (Async (Worker env)) @@ a))
 -> WorkerConfigs env rec -> m (rec (ConstFn (Async (Worker env)))))
-> (forall a.
    Metadata a
    -> (ConstFn (WorkerConfig env) @@ a)
    -> m (ConstFn (Async (Worker env)) @@ a))
-> WorkerConfigs env rec
-> m (rec (ConstFn (Async (Worker env))))
forall a b. (a -> b) -> a -> b
$ \Metadata a
_ ConstFn (WorkerConfig env) @@ a
workerConfig -> (LoggingT m (Async (Worker env))
 -> (Loc -> Text -> LogLevel -> LogStr -> IO ())
 -> m (ConstFn (Async (Worker env)) @@ a))
-> (Loc -> Text -> LogLevel -> LogStr -> IO ())
-> LoggingT m (Async (Worker env))
-> m (ConstFn (Async (Worker env)) @@ a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip LoggingT m (Async (Worker env))
-> (Loc -> Text -> LogLevel -> LogStr -> IO ())
-> m (Async (Worker env))
LoggingT m (Async (Worker env))
-> (Loc -> Text -> LogLevel -> LogStr -> IO ())
-> m (ConstFn (Async (Worker env)) @@ a)
forall (m :: * -> *) a.
LoggingT m a -> (Loc -> Text -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT ConstFn (WorkerConfig env) @@ a
WorkerConfig env
workerConfig.logger (LoggingT m (Async (Worker env))
 -> m (ConstFn (Async (Worker env)) @@ a))
-> LoggingT m (Async (Worker env))
-> m (ConstFn (Async (Worker env)) @@ a)
forall a b. (a -> b) -> a -> b
$ do
      String
-> LoggingT m (Worker env) -> LoggingT m (Async (Worker env))
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> m a -> m (Async a)
asyncLabelled String
"temporal/startTaskQueues" (Client -> WorkerConfig env -> LoggingT m (Worker env)
forall (m :: * -> *) actEnv.
(MonadUnliftIO m, MonadCatch m) =>
Client -> WorkerConfig actEnv -> m (Worker actEnv)
startWorker Client
client ConstFn (WorkerConfig env) @@ a
WorkerConfig env
workerConfig)
    awaitWorkersStart :: rec (ConstFn (Async (Worker env))) -> m (rec (ConstFn (Worker env)))
    awaitWorkersStart :: rec (ConstFn (Async (Worker env))) -> m (Workers env rec)
awaitWorkersStart = (forall a.
 Metadata a
 -> (ConstFn (Async (Worker env)) @@ a)
 -> m (ConstFn (Worker env) @@ a))
-> rec (ConstFn (Async (Worker env))) -> m (Workers env rec)
forall (e :: * -> *) (f :: * -> * -> *) (g :: * -> * -> *).
Applicative e =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
forall (rec :: (* -> * -> *) -> *) (e :: * -> *) (f :: * -> * -> *)
       (g :: * -> * -> *).
(TraversableRec rec, Applicative e) =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
Rec.traverse (\Metadata a
_ ConstFn (Async (Worker env)) @@ a
workerStartupThread -> Async (Worker env) -> m (Worker env)
forall (m :: * -> *) a. MonadIO m => Async a -> m a
UnliftIO.wait Async (Worker env)
ConstFn (Async (Worker env)) @@ a
workerStartupThread)


{- | Stop each Temporal worker for each task queue specified in the MercuryTaskQueues record.

This function stops each worker concurrently, waits for them to complete shutdown (gracefully or not), and then returns.
-}
shutdownTaskQueues :: forall m rec env. (TraversableRec rec, MonadUnliftIO m) => Workers env rec -> m (rec (ConstFn (Either SomeException ())))
shutdownTaskQueues :: forall (m :: * -> *) (rec :: (* -> * -> *) -> *) env.
(TraversableRec rec, MonadUnliftIO m) =>
Workers env rec -> m (rec (ConstFn (Either SomeException ())))
shutdownTaskQueues Workers env rec
workers =
  Workers env rec -> m (rec (ConstFn (Async ())))
stopWorkers Workers env rec
workers
    m (rec (ConstFn (Async ())))
-> (rec (ConstFn (Async ()))
    -> m (rec (ConstFn (Either SomeException ()))))
-> m (rec (ConstFn (Either SomeException ())))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= rec (ConstFn (Async ()))
-> m (rec (ConstFn (Either SomeException ())))
awaitWorkersStop
  where
    stopWorkers :: rec (ConstFn (Worker env)) -> m (rec (ConstFn (Async ())))
    stopWorkers :: Workers env rec -> m (rec (ConstFn (Async ())))
stopWorkers = (forall a.
 Metadata a
 -> (ConstFn (Worker env) @@ a) -> m (ConstFn (Async ()) @@ a))
-> Workers env rec -> m (rec (ConstFn (Async ())))
forall (e :: * -> *) (f :: * -> * -> *) (g :: * -> * -> *).
Applicative e =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
forall (rec :: (* -> * -> *) -> *) (e :: * -> *) (f :: * -> * -> *)
       (g :: * -> * -> *).
(TraversableRec rec, Applicative e) =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
Rec.traverse ((forall a.
  Metadata a
  -> (ConstFn (Worker env) @@ a) -> m (ConstFn (Async ()) @@ a))
 -> Workers env rec -> m (rec (ConstFn (Async ()))))
-> (forall a.
    Metadata a
    -> (ConstFn (Worker env) @@ a) -> m (ConstFn (Async ()) @@ a))
-> Workers env rec
-> m (rec (ConstFn (Async ())))
forall a b. (a -> b) -> a -> b
$ \Metadata a
_ ConstFn (Worker env) @@ a
worker -> String -> m () -> m (Async ())
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> m a -> m (Async a)
asyncLabelled String
"temporal/shutdownTaskQueues" (Worker env -> m ()
forall (m :: * -> *) actEnv.
MonadUnliftIO m =>
Worker actEnv -> m ()
shutdown ConstFn (Worker env) @@ a
Worker env
worker)
    awaitWorkersStop :: rec (ConstFn (Async ())) -> m (rec (ConstFn (Either SomeException ())))
    awaitWorkersStop :: rec (ConstFn (Async ()))
-> m (rec (ConstFn (Either SomeException ())))
awaitWorkersStop = (forall a.
 Metadata a
 -> (ConstFn (Async ()) @@ a)
 -> m (ConstFn (Either SomeException ()) @@ a))
-> rec (ConstFn (Async ()))
-> m (rec (ConstFn (Either SomeException ())))
forall (e :: * -> *) (f :: * -> * -> *) (g :: * -> * -> *).
Applicative e =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
forall (rec :: (* -> * -> *) -> *) (e :: * -> *) (f :: * -> * -> *)
       (g :: * -> * -> *).
(TraversableRec rec, Applicative e) =>
(forall a. Metadata a -> (f @@ a) -> e (g @@ a))
-> rec f -> e (rec g)
Rec.traverse ((forall a.
  Metadata a
  -> (ConstFn (Async ()) @@ a)
  -> m (ConstFn (Either SomeException ()) @@ a))
 -> rec (ConstFn (Async ()))
 -> m (rec (ConstFn (Either SomeException ()))))
-> (forall a.
    Metadata a
    -> (ConstFn (Async ()) @@ a)
    -> m (ConstFn (Either SomeException ()) @@ a))
-> rec (ConstFn (Async ()))
-> m (rec (ConstFn (Either SomeException ())))
forall a b. (a -> b) -> a -> b
$ \Metadata a
_ ConstFn (Async ()) @@ a
workerShutdownThread -> Async () -> m (Either SomeException ())
forall (m :: * -> *) a.
MonadIO m =>
Async a -> m (Either SomeException a)
UnliftIO.waitCatch Async ()
ConstFn (Async ()) @@ a
workerShutdownThread


linkTaskQueues :: forall m rec env. (TraversableRec rec, MonadUnliftIO m) => Workers env rec -> m ()
linkTaskQueues :: forall (m :: * -> *) (rec :: (* -> * -> *) -> *) env.
(TraversableRec rec, MonadUnliftIO m) =>
Workers env rec -> m ()
linkTaskQueues = (forall a. Metadata a -> (ConstFn (Worker env) @@ a) -> m ())
-> rec (ConstFn (Worker env)) -> m ()
forall (e :: * -> *) (f :: * -> * -> *) c.
Applicative e =>
(forall a. Metadata a -> (f @@ a) -> e c) -> rec f -> e ()
forall (rec :: (* -> * -> *) -> *) (e :: * -> *) (f :: * -> * -> *)
       c.
(TraversableRec rec, Applicative e) =>
(forall a. Metadata a -> (f @@ a) -> e c) -> rec f -> e ()
Rec.traverse_ (\Metadata a
_ -> IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Worker env -> IO ()) -> Worker env -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Worker env -> IO ()
forall actEnv. Worker actEnv -> IO ()
linkWorker)


withTaskQueues :: forall rec m env a. (TraversableRec rec, MonadUnliftIO m, MonadCatch m) => Client -> WorkerConfigs env rec -> (Workers env rec -> m a) -> m a
withTaskQueues :: forall (rec :: (* -> * -> *) -> *) (m :: * -> *) env a.
(TraversableRec rec, MonadUnliftIO m, MonadCatch m) =>
Client -> WorkerConfigs env rec -> (Workers env rec -> m a) -> m a
withTaskQueues Client
client WorkerConfigs env rec
conf Workers env rec -> m a
f = m (Workers env rec)
-> (Workers env rec -> m (rec (ConstFn (Either SomeException ()))))
-> (Workers env rec -> m a)
-> m a
forall (m :: * -> *) a b c.
MonadUnliftIO m =>
m a -> (a -> m b) -> (a -> m c) -> m c
UnliftIO.bracket (Client -> WorkerConfigs env rec -> m (Workers env rec)
forall (rec :: (* -> * -> *) -> *) (m :: * -> *) env.
(TraversableRec rec, MonadUnliftIO m, MonadCatch m) =>
Client -> WorkerConfigs env rec -> m (Workers env rec)
startTaskQueues Client
client WorkerConfigs env rec
conf) Workers env rec -> m (rec (ConstFn (Either SomeException ())))
forall (m :: * -> *) (rec :: (* -> * -> *) -> *) env.
(TraversableRec rec, MonadUnliftIO m) =>
Workers env rec -> m (rec (ConstFn (Either SomeException ())))
shutdownTaskQueues ((Workers env rec -> m a) -> m a)
-> (Workers env rec -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Workers env rec
ws -> Workers env rec -> m ()
forall (m :: * -> *) (rec :: (* -> * -> *) -> *) env.
(TraversableRec rec, MonadUnliftIO m) =>
Workers env rec -> m ()
linkTaskQueues Workers env rec
ws m () -> m a -> m a
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Workers env rec -> m a
f Workers env rec
ws