graphql-engine/server/src-test/Hasura/AppSpec.hs
awjchen 329f3f0a39 multitenant: make shutdown logic more abstract
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5836
GitOrigin-RevId: 2f94cdee01702e49ff130f6a40f6be26fa69ec88
2022-11-23 07:53:19 +00:00

73 lines
2.2 KiB
Haskell

{-# LANGUAGE NumericUnderscores #-}
module Hasura.AppSpec (spec) where
import Control.Concurrent.Async qualified as Async
import Control.Concurrent.Extended (sleep)
import Control.Exception (throwIO)
import Hasura.Prelude
import Hasura.ShutdownLatch (newShutdownLatch, shutdownGracefully, shuttingDown, waitForShutdown)
import System.Timeout (timeout)
import Test.Hspec
spec :: Spec
spec = do
describe "ShutdownLatch" shutdownLatchSpec
shutdownLatchSpec :: Spec
shutdownLatchSpec = do
it "waitForShutdown blocks before shutdown, not after" $ do
latch <- newShutdownLatch
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Nothing
timeout 10_000 (shutdownGracefully latch)
`shouldReturn` Just ()
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Just ()
it "allows multiple calls to shutdownGracefully" $ do
latch <- newShutdownLatch
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Nothing
timeout 10_000 (shutdownGracefully latch)
`shouldReturn` Just ()
timeout 10_000 (shutdownGracefully latch)
`shouldReturn` Just ()
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Just ()
it "allows shutting down a thread" $ do
latch <- newShutdownLatch
Async.withAsync (waitForShutdown latch >> return ("shut down" :: String)) $ \async -> do
sleep 0.01
pollThrow async
`shouldReturn` Nothing
shutdownGracefully latch
timeout 1_000_000 (Async.wait async)
`shouldReturn` Just "shut down"
it "allows multiple threads to wait for shutdown" $ do
latch <- newShutdownLatch
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Nothing
shutdownGracefully latch
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Just ()
timeout 10_000 (waitForShutdown latch)
`shouldReturn` Just ()
it "checks if a latch is ready for shutdown" $ do
latch <- newShutdownLatch
shuttingDown latch `shouldReturn` False
shutdownGracefully latch
shuttingDown latch `shouldReturn` True
pollThrow :: Async.Async a -> IO (Maybe a)
pollThrow async = do
res <- Async.poll async
case res of
Just (Left e) -> throwIO e
Just (Right x) -> pure $ Just x
Nothing -> pure Nothing