module Ecluse.Core.Server.Admission (
ServeAdmission,
newServeAdmission,
withServeAdmission,
newServeAdmissionTuned,
) where
import UnliftIO (MonadUnliftIO)
import Ecluse.Core.Server.Admission.Weighted (
AdmissionObservers (..),
WeightedAdmission,
admissionWaitMicros,
newWeightedAdmission,
withWeightedAdmission,
)
import Ecluse.Core.Telemetry.Record (MetricsPort (..))
newtype ServeAdmission = ServeAdmission WeightedAdmission
newServeAdmission :: Int -> IO ServeAdmission
newServeAdmission :: Int -> IO ServeAdmission
newServeAdmission Int
capacity
| Int
capacity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Text -> IO ServeAdmission
forall a t. (HasCallStack, IsText t) => t -> a
error Text
"ServeAdmission capacity must be positive"
| Bool
otherwise = Int -> Int -> Int -> IO ServeAdmission
newServeAdmissionTuned Int
capacity Int
capacity Int
admissionWaitMicros
newServeAdmissionTuned :: Int -> Int -> Int -> IO ServeAdmission
newServeAdmissionTuned :: Int -> Int -> Int -> IO ServeAdmission
newServeAdmissionTuned Int
capacity Int
room Int
waitMicros =
WeightedAdmission -> ServeAdmission
ServeAdmission (WeightedAdmission -> ServeAdmission)
-> IO WeightedAdmission -> IO ServeAdmission
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> Int -> IO WeightedAdmission
newWeightedAdmission Int
capacity Int
room Int
waitMicros
{-# INLINE withServeAdmission #-}
withServeAdmission :: (MonadUnliftIO m) => MetricsPort -> ServeAdmission -> m a -> m (Maybe a)
withServeAdmission :: forall (m :: * -> *) a.
MonadUnliftIO m =>
MetricsPort -> ServeAdmission -> m a -> m (Maybe a)
withServeAdmission MetricsPort
metrics (ServeAdmission WeightedAdmission
core) =
AdmissionObservers
-> WeightedAdmission -> Int -> m a -> m (Maybe a)
forall (m :: * -> *) a.
MonadUnliftIO m =>
AdmissionObservers
-> WeightedAdmission -> Int -> m a -> m (Maybe a)
withWeightedAdmission AdmissionObservers
observers WeightedAdmission
core Int
1
where
observers :: AdmissionObservers
observers =
AdmissionObservers
{ onQueued :: IO ()
onQueued = MetricsPort -> IO ()
mpServeAdmissionQueued MetricsPort
metrics
, onShed :: IO ()
onShed = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
, onInFlightDelta :: Int -> IO ()
onInFlightDelta = MetricsPort -> Int -> IO ()
mpServeAdmissionInFlight MetricsPort
metrics
}