you're telling me a puppy coded this??
{-# LANGUAGE TemplateHaskell #-}

-- | An effect for {en,de}queueing tasks of a particular type
-- through concurrent channels.
module Puppy.TaskQueue (
  -- * A basic effect for talking to other threads
  TaskQueue,
  enqueue,
  dequeue,
  runTaskQueue,
  -- * Task types
  PerformTask (..),
  DeliverTask (..),
) where

import Effectful
import Effectful.Concurrent.Chan
import Effectful.Dispatch.Dynamic
import Effectful.TH (makeEffect)
import Puppy.Types (Channel)
import qualified Puppy.Protocol.ActivityStreams as AS

-- | Schedule work through a task queue.
data TaskQueue work :: Effect where
  Enqueue :: work -> TaskQueue work m ()
  Dequeue :: TaskQueue work m work

makeEffect ''TaskQueue

runTaskQueue
  :: forall task es a. 
     (Concurrent :> es)
  => Eff (TaskQueue task : es) a
  -> Eff es a
runTaskQueue eff = do
  chan <- newChan 
  interpret (run chan) eff
  where
    run :: (Concurrent :> es)
        => Chan task
        -> LocalEnv localEs es
        -> TaskQueue task (Eff localEs) x
        -> Eff es x
    run chan _ = \case
      Enqueue v -> writeChan chan v
      Dequeue -> readChan chan

data PerformTask
  = PerformTask (AS.Activity AS.Object) Channel

data DeliverTask
  = DeliverTask (AS.Activity AS.Object) Channel