polysemy-hasql-0.0.1.0: lib/Polysemy/Hasql/Queue/Output.hs
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))
-- TODO I think notify doesn't even need a unique connection, only listen does
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 =
interpretResumable \case
Output d -> do
id' <- random
created <- Time.now
resumeHoist QueueOutputError.Insert do
Store.insert (Uid id' (Queued created d))
Log.debug [exon|executing `notify` for queue '#{symbolText @queue}'|]
resumeHoist QueueOutputError.Notify do
Database.retryingSql (Seconds 3) (sql id')
where
sql id' =
[exon|notify "#{Sql (symbolText @queue)}", '#{show id'}'|]