http-client 0.4.1 → 0.4.2
raw patch · 5 files changed
+29/−9 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Network.HTTP.Client: instance Typeable HistoriedResponse
+ Network.HTTP.Client: instance Typeable1 HistoriedResponse
+ Network.HTTP.Client.Internal: mConnsBaton :: Manager -> MVar ()
- Network.HTTP.Client.Internal: Manager :: IORef ConnsMap -> Int -> Maybe Int -> (Maybe HostAddress -> String -> Int -> IO Connection) -> (Maybe HostAddress -> String -> Int -> IO Connection) -> (ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection) -> (SomeException -> Bool) -> (forall a. IO a -> IO a) -> Int -> Manager
+ Network.HTTP.Client.Internal: Manager :: IORef ConnsMap -> MVar () -> Int -> Maybe Int -> (Maybe HostAddress -> String -> Int -> IO Connection) -> (Maybe HostAddress -> String -> Int -> IO Connection) -> (ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection) -> (SomeException -> Bool) -> (forall a. IO a -> IO a) -> Int -> Manager
Files
- ChangeLog.md +4/−0
- Network/HTTP/Client/Manager.hs +14/−5
- Network/HTTP/Client/MultipartFormData.hs +3/−3
- Network/HTTP/Client/Types.hs +7/−0
- http-client.cabal +1/−1
ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.4.2++The reaper thread for a manager will go to sleep completely when there are no connection to manage. See: https://github.com/snoyberg/http-client/issues/70+ ## 0.4.1 * Provide the `responseOpenHistory`/`withResponseHistory` API. See: https://github.com/snoyberg/http-client/pull/79
Network/HTTP/Client/Manager.hs view
@@ -32,7 +32,7 @@ import qualified Data.Text as T import Control.Monad.IO.Class (MonadIO, liftIO)-import Control.Monad (unless, join)+import Control.Monad (unless, join, when, void) import Control.Exception (mask_, SomeException, bracket, catch, throwIO, fromException, mask, IOException, Exception (..), handle) import Control.Concurrent (forkIO, threadDelay) import Data.Time (UTCTime (..), Day (..), DiffTime, getCurrentTime, addUTCTime)@@ -47,6 +47,7 @@ import Network.HTTP.Client.Types import Network.HTTP.Client.Connection import Network.HTTP.Client.Headers (parseStatusHeaders)+import Control.Concurrent.MVar (MVar, takeMVar, tryPutMVar, newEmptyMVar) -- | A value for the @managerRawConnection@ setting, but also allows you to -- modify the underlying @Socket@ to set additional settings. For a motivating@@ -112,6 +113,7 @@ putSocket man key ci = do now <- getCurrentTime join $ I.atomicModifyIORef (mConns man) (go now)+ void $ tryPutMVar (mConnsBaton man) () where go _ ManagerClosed = (ManagerClosed , connectionClose ci) go now mc@(ManagerOpen idleCount m)@@ -153,10 +155,12 @@ tlsConnection <- managerTlsConnection ms tlsProxyConnection <- managerTlsProxyConnection ms mapRef <- I.newIORef $! ManagerOpen 0 Map.empty+ baton <- newEmptyMVar wmapRef <- I.mkWeakIORef mapRef $ closeManager' mapRef- _ <- forkIO $ reap wmapRef+ _ <- forkIO $ reap baton wmapRef let manager = Manager { mConns = mapRef+ , mConnsBaton = baton , mMaxConns = managerConnCount ms , mResponseTimeout = managerResponseTimeout ms , mRawConnection = rawConnection@@ -169,8 +173,8 @@ return manager -- | Collect and destroy any stale connections.-reap :: Weak (I.IORef ConnsMap) -> IO ()-reap wmapRef =+reap :: MVar () -> Weak (I.IORef ConnsMap) -> IO ()+reap baton wmapRef = mask_ loop where loop = do@@ -183,8 +187,13 @@ goMapRef mapRef = do now <- getCurrentTime let isNotStale time = 30 `addUTCTime` time >= now- toDestroy <- I.atomicModifyIORef mapRef (findStaleWrap isNotStale)+ (newMap, toDestroy) <- I.atomicModifyIORef mapRef $ \m ->+ let (newMap, toDestroy) = findStaleWrap isNotStale m+ in (newMap, (newMap, toDestroy)) mapM_ safeConnClose toDestroy+ case newMap of+ ManagerOpen _ m | not $ Map.null m -> return ()+ _ -> takeMVar baton loop findStaleWrap _ ManagerClosed = (ManagerClosed, []) findStaleWrap isNotStale (ManagerOpen idleCount m) =
Network/HTTP/Client/MultipartFormData.hs view
@@ -3,14 +3,14 @@ -- -- > {-# LANGUAGE OverloadedStrings #-} -- > import Network--- > import Network.HTTP.Conduit--- > import Network.HTTP.Conduit.MultipartFormData+-- > import Network.HTTP.Client+-- > import Network.HTTP.Client.MultipartFormData -- > -- > import Data.Text.Encoding as TE -- > -- > import Control.Monad -- >--- > main = withSocketsDo $ withManager $ \m -> do+-- > main = withSocketsDo $ void $ withManager defaultManagerSettings $ \m -> do -- > req1 <- parseUrl "http://random-cat-photo.net/cat.jpg" -- > res <- httpLbs req1 m -- > req2 <- parseUrl "http://example.org/~friedrich/blog/addPost.hs"
Network/HTTP/Client/Types.hs view
@@ -50,6 +50,7 @@ import qualified Data.Map as Map import Data.Text (Text) import Data.Streaming.Zlib (ZlibException)+import Control.Concurrent.MVar (MVar) -- | An @IO@ action that represents an incoming response body coming from the -- server. Data provided by this action has already been gunzipped and@@ -505,6 +506,12 @@ data Manager = Manager { mConns :: I.IORef ConnsMap -- ^ @Nothing@ indicates that the manager is closed.+ , mConnsBaton :: MVar ()+ -- ^ Used to indicate to the reaper thread that it has some work to do.+ -- This must be filled every time a connection is returned to the manager.+ -- While redundant with the @IORef@ above, this allows us to have the+ -- reaper thread fully blocked instead of running every 5 seconds when+ -- there are no connections to manage. , mMaxConns :: Int -- ^ This is a per-@ConnKey@ value. , mResponseTimeout :: Maybe Int
http-client.cabal view
@@ -1,5 +1,5 @@ name: http-client-version: 0.4.1+version: 0.4.2 synopsis: An HTTP client engine, intended as a base layer for more user-friendly packages. description: This codebase has been refactored from http-conduit. homepage: https://github.com/snoyberg/http-client