module Kafka.Worker.Stopping
  ( init,
    stopTakingRequests,
    runUnlessStopping,
    Stopping,
  )
where

import qualified Control.Concurrent.Async as Async
import qualified Control.Concurrent.MVar as MVar
import qualified Prelude

newtype Stopping = Stopping (MVar.MVar ())

init :: Prelude.IO Stopping
init :: IO Stopping
init = IO (MVar ())
forall a. IO (MVar a)
MVar.newEmptyMVar IO (MVar ()) -> (IO (MVar ()) -> IO Stopping) -> IO Stopping
forall a b. a -> (a -> b) -> b
|> (MVar () -> Stopping) -> IO (MVar ()) -> IO Stopping
forall (m :: * -> *) a value.
Functor m =>
(a -> value) -> m a -> m value
map MVar () -> Stopping
Stopping

stopTakingRequests :: Stopping -> Prelude.IO ()
stopTakingRequests :: Stopping -> IO ()
stopTakingRequests (Stopping MVar ()
stopping) = do
  String -> IO ()
Prelude.putStrLn String
"Gracefully shutting down..."
  MVar () -> () -> IO Bool
forall a. MVar a -> a -> IO Bool
MVar.tryPutMVar MVar ()
stopping ()
    IO Bool -> (IO Bool -> IO ()) -> IO ()
forall a b. a -> (a -> b) -> b
|> (Bool -> ()) -> IO Bool -> IO ()
forall (m :: * -> *) a value.
Functor m =>
(a -> value) -> m a -> m value
map (\Bool
_ -> ())

runUnlessStopping :: Stopping -> a -> Prelude.IO a -> Prelude.IO a
runUnlessStopping :: Stopping -> a -> IO a -> IO a
runUnlessStopping (Stopping MVar ()
stopping) a
stoppingVal IO a
action =
  IO () -> IO a -> IO (Either () a)
forall a b. IO a -> IO b -> IO (Either a b)
Async.race
    (MVar () -> IO ()
forall a. MVar a -> IO a
MVar.readMVar MVar ()
stopping)
    IO a
action
    IO (Either () a) -> (IO (Either () a) -> IO a) -> IO a
forall a b. a -> (a -> b) -> b
|> (Either () a -> a) -> IO (Either () a) -> IO a
forall (m :: * -> *) a value.
Functor m =>
(a -> value) -> m a -> m value
map
      ( \Either () a
either ->
          case Either () a
either of
            Prelude.Left () -> a
stoppingVal
            Prelude.Right a
r -> a
r
      )