module Polysemy.Hasql.Queue.Output where
import Data.UUID (UUID)
import Exon (exon)
import Polysemy.Db.Data.DbError (DbError)
import Polysemy.Db.Effect.Random (Random, random)
import qualified Polysemy.Db.Effect.Store as Store
import Polysemy.Db.Effect.Store (Store)
import qualified Log
import Polysemy.Output (Output (Output))
import qualified Time as Time
import Time (Seconds (Seconds))
import Prelude hiding (Queue, group)
import Sqel.Data.Sql (Sql (Sql))
import Sqel.Data.Uid (Uid (Uid))
import Sqel.SOP.Constraint (symbolText)
import qualified Polysemy.Hasql.Data.QueueOutputError as QueueOutputError
import Polysemy.Hasql.Data.QueueOutputError (QueueOutputError)
import qualified Polysemy.Hasql.Database as Database (retryingSql)
import Polysemy.Hasql.Effect.Database (Database)
import Polysemy.Hasql.Queue.Data.Queued (Queued (Queued))
interpretOutputQueueDb ::
∀ (queue :: Symbol) d t dt r .
KnownSymbol queue =>
Members [Store UUID (Queued t d) !! DbError, Database !! DbError, Time t dt, Log, Random UUID, Embed IO] r =>
InterpreterFor (Output d !! QueueOutputError) r
interpretOutputQueueDb :: forall (queue :: Symbol) d t dt (r :: EffectRow).
(KnownSymbol queue,
Members
'[Store UUID (Queued t d) !! DbError, Database !! DbError,
Time t dt, Log, Random UUID, Embed IO]
r) =>
InterpreterFor (Output d !! QueueOutputError) r
interpretOutputQueueDb =
forall err (eff :: (* -> *) -> * -> *) (r :: EffectRow).
FirstOrder eff "interpretResumable" =>
(forall x (r0 :: EffectRow).
eff (Sem r0) x -> Sem (Stop err : r) x)
-> InterpreterFor (Resumable err eff) r
interpretResumable \case
Output d
d -> do
UUID
id' <- forall a (r :: EffectRow). Member (Random a) r => Sem r a
random
t
created <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now
forall err (eff :: (* -> *) -> * -> *) err' (r :: EffectRow) a.
Members '[Resumable err eff, Stop err'] r =>
(err -> err') -> Sem (eff : r) a -> Sem r a
resumeHoist DbError -> QueueOutputError
QueueOutputError.Insert do
forall (f :: * -> *) i d (r :: EffectRow).
Member (QStore f i d) r =>
d -> Sem r ()
Store.insert (forall i a. i -> a -> Uid i a
Uid UUID
id' (forall t a. t -> a -> Queued t a
Queued t
created d
d))
forall (r :: EffectRow).
(HasCallStack, Member Log r) =>
Text -> Sem r ()
Log.debug [exon|executing `notify` for queue '#{symbolText @queue}'|]
forall err (eff :: (* -> *) -> * -> *) err' (r :: EffectRow) a.
Members '[Resumable err eff, Stop err'] r =>
(err -> err') -> Sem (eff : r) a -> Sem r a
resumeHoist DbError -> QueueOutputError
QueueOutputError.Notify do
forall t (r :: EffectRow).
(TimeUnit t, Member Database r) =>
t -> Sql -> Sem r ()
Database.retryingSql (Int64 -> Seconds
Seconds Int64
3) (UUID -> Sql
sql UUID
id')
where
sql :: UUID -> Sql
sql UUID
id' =
[exon|notify "#{Sql (symbolText @queue)}", '#{show id'}'|]