Skip to content

Commit

Permalink
feat(sut): add common http client for dumblog
Browse files Browse the repository at this point in the history
  • Loading branch information
symbiont-stevan-andjelkovic committed Feb 21, 2022
1 parent 5f11e49 commit 11cccee
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/sut/dumblog/dumblog.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ library
, containers
, directory
, filepath
, http-client
, http-types
, journal
, sqlite-simple
Expand All @@ -46,6 +47,7 @@ library
, warp

exposed-modules:
Dumblog.Common.HttpClient
Dumblog.Journal.Blocker
Dumblog.Journal.Codec
Dumblog.Journal.FrontEnd
Expand Down
80 changes: 80 additions & 0 deletions src/sut/dumblog/src/Dumblog/Common/HttpClient.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{-# LANGUAGE OverloadedStrings #-}

module Dumblog.Common.HttpClient where

import Control.Monad (when)
import qualified Data.ByteString.Char8 as BSChar8
import Data.ByteString.Lazy.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as LBSChar8
import Network.HTTP.Client
( Manager
, Request
, RequestBody(RequestBodyLBS)
, defaultManagerSettings
, httpLbs
, httpNoBody
, method
, newManager
, parseRequest
, path
, requestBody
, responseBody
, responseStatus
)
import Network.HTTP.Types.Status (ok200)
import Network.Wai.Handler.Warp (Port)

------------------------------------------------------------------------

data HttpClient = HttpClient
{ hcManager :: Manager -- | NOTE: If possible, you should share a single
-- `Manager` between multiple threads and requests.
, hcWriteReq :: ByteString -> Request
, hcReadReq :: Int -> Request
-- , hcErrors :: AtomicCounter
}

newHttpClient :: String -> Port -> IO HttpClient
newHttpClient host port = do
mgr <- newManager defaultManagerSettings
initReq <- parseRequest ("http://" ++ host ++ ":" ++ show port)

let writeReq :: ByteString -> Request
writeReq bs = initReq { method = "POST"
, requestBody = RequestBodyLBS bs
}

readReq :: Int -> Request
readReq ix = initReq { method = "GET"
, path = path initReq <> BSChar8.pack (show ix)
}

return (HttpClient mgr writeReq readReq)

writeHttp :: HttpClient -> ByteString -> IO Int
writeHttp hc bs = do
resp <- httpLbs (hcWriteReq hc bs) (hcManager hc)
when (responseStatus resp /= ok200) $
return () -- XXX: increment hcErrors
return (read (LBSChar8.unpack (responseBody resp)))

readHttp :: HttpClient -> Int -> IO ByteString
readHttp hc ix = do
resp <- httpLbs (hcReadReq hc ix) (hcManager hc)
when (responseStatus resp /= ok200) $
return () -- XXX: increment hcErrors
return (responseBody resp)

writeHttp_ :: HttpClient -> ByteString -> IO ()
writeHttp_ hc bs = do
resp <- httpNoBody (hcWriteReq hc bs) (hcManager hc)
when (responseStatus resp /= ok200) $
return () -- XXX: increment hcErrors
return ()

readHttp_ :: HttpClient -> Int -> IO ()
readHttp_ hc ix = do
resp <- httpNoBody (hcReadReq hc ix) (hcManager hc)
when (responseStatus resp /= ok200) $
return () -- XXX: increment hcErrors
return ()
2 changes: 1 addition & 1 deletion src/sut/dumblog/src/Dumblog/SQLite/FrontEnd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ httpFrontend queue req respond =
parseIndex :: Either ByteString Int
parseIndex =
case pathInfo req of
[t] -> case decimal t of
[txt] -> case decimal txt of
Right (ix, _rest) -> Right ix
_otherwise -> Left (BSChar8.pack "parseIndex: GET /:ix, :ix isn't an integer")
_otherwise -> Left (BSChar8.pack "parseIndex: GET /:ix, :ix missing")
Expand Down

0 comments on commit 11cccee

Please sign in to comment.