module System.Metrics.Prometheus.Metric.Gauge ( Gauge , GaugeSample (..) , new , add , sub , inc , dec , set , sample , modifyAndSample ) where import Data.IORef (IORef, atomicModifyIORef', atomicWriteIORef, newIORef, readIORef) newtype Gauge = Gauge { unGauge :: IORef Double } newtype GaugeSample = GaugeSample { unGaugeSample :: Double } new :: IO Gauge new = Gauge <$> newIORef 0 modifyAndSample :: (Double -> (Double, a)) -> Gauge -> IO a modifyAndSample f = flip atomicModifyIORef' f . unGauge add :: Double -> Gauge -> IO () add x = modifyAndSample f where f v = (v + x, ()) sub :: Double -> Gauge -> IO () sub x = modifyAndSample f where f v = (v - x, ()) inc :: Gauge -> IO () inc = add 1 dec :: Gauge -> IO () dec = sub 1 set :: Double -> Gauge -> IO () set x = flip atomicWriteIORef x . unGauge sample :: Gauge -> IO GaugeSample sample = fmap GaugeSample . readIORef . unGauge