#if __GLASGOW_HASKELL__ >= 800
#else
#endif
module Database.InfluxDB.Ping
(
ping
, PingParams
, pingParams
, server
, manager
, timeout
, Pong
, roundtripTime
, influxdbVersion
) where
import Control.Exception
import Control.Lens
import Data.Time.Clock (NominalDiffTime)
import System.Clock
import qualified Data.ByteString as BS
import qualified Data.Text.Encoding as TE
import qualified Network.HTTP.Client as HC
import Database.InfluxDB.Types as Types
data PingParams = PingParams
{ pingServer :: !Server
, pingManager :: !(Either HC.ManagerSettings HC.Manager)
, pingTimeout :: !(Maybe NominalDiffTime)
}
pingParams :: PingParams
pingParams = PingParams
{ pingServer = defaultServer
, pingManager = Left HC.defaultManagerSettings
, pingTimeout = Nothing
}
makeLensesWith
( lensRules
& generateSignatures .~ False
& lensField .~ lookingupNamer
[ ("pingServer", "_server")
, ("pingManager", "_manager")
, ("pingTimeout", "timeout")
]
)
''PingParams
instance HasServer PingParams where
server = _server
instance HasManager PingParams where
manager = _manager
timeout :: Lens' PingParams (Maybe NominalDiffTime)
pingRequest :: PingParams -> HC.Request
pingRequest PingParams {..} = HC.defaultRequest
{ HC.host = TE.encodeUtf8 _host
, HC.port = fromIntegral _port
, HC.secure = _ssl
, HC.method = "GET"
, HC.path = "/ping"
}
where
Server {..} = pingServer
data Pong = Pong
{ _roundtripTime :: !TimeSpec
, _influxdbVersion :: !BS.ByteString
} deriving (Show, Eq, Ord)
makeLensesWith (lensRules & generateSignatures .~ False) ''Pong
roundtripTime :: Lens' Pong TimeSpec
influxdbVersion :: Lens' Pong BS.ByteString
ping :: PingParams -> IO Pong
ping params = do
manager' <- either HC.newManager return $ pingManager params
startTime <- getTimeMonotonic
HC.withResponse request manager' $ \response -> do
endTime <- getTimeMonotonic
case lookup "X-Influxdb-Version" (HC.responseHeaders response) of
Just version ->
return $! Pong (diffTimeSpec endTime startTime) version
Nothing ->
throwIO $ UnexpectedResponse
"The X-Influxdb-Version header was missing in the response."
request
""
`catch` (throwIO . HTTPException)
where
request = (pingRequest params)
{ HC.responseTimeout = case pingTimeout params of
Nothing -> HC.responseTimeoutNone
Just sec -> HC.responseTimeoutMicro $
round $ realToFrac sec / (10**(6) :: Double)
}
getTimeMonotonic = getTime Monotonic