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