Skip to content

Commit 7210905

Browse files
author
Arjun Guha
committed
fixed closing connections
1 parent 1a95ba7 commit 7210905

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

src/Database/CouchDB/HTTP.hs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ module Database.CouchDB.HTTP
1111
, runCouchDB'
1212
) where
1313

14+
import Data.IORef
15+
import Control.Concurrent
1416
import System.Log.Logger (errorM,debugM,infoM)
1517
import Network.TCP
1618
import Network.Stream
1719
import Network.HTTP
1820
import Network.URI
21+
import Control.Exception (finally)
1922
import Control.Monad.Trans (MonadIO (..))
2023

2124
-- |Describes a connection to a CouchDB database. This type is
2225
-- encapsulated by 'CouchMonad'.
2326
data CouchConn = CouchConn
24-
{ ccConn :: Connection
27+
{ ccConn :: IORef Connection
2528
, ccURI :: URI
2629
, ccHostname :: String
2730
, ccPort :: Int
@@ -60,13 +63,16 @@ makeURL path query = CouchMonad $ \conn -> do
6063
,conn )
6164

6265
getConn :: CouchMonad Connection
63-
getConn = CouchMonad $ \conn -> return (ccConn conn,conn)
66+
getConn = CouchMonad $ \conn -> do
67+
r <- readIORef (ccConn conn)
68+
return (r,conn)
6469

6570
reopenConnection :: CouchMonad ()
6671
reopenConnection = CouchMonad $ \conn -> do
67-
liftIO $ close (ccConn conn) -- prevent memory leak
72+
c <- liftIO $ readIORef (ccConn conn) >>= close
6873
connection <- liftIO $ openTCPPort (ccHostname conn) (ccPort conn)
69-
return ((), conn {ccConn = connection})
74+
writeIORef (ccConn conn) connection
75+
return ((), conn)
7076

7177
makeHeaders bodyLen =
7278
[ Header HdrContentType "application/json"
@@ -88,6 +94,7 @@ request path query method headers body = do
8894
let allHeaders = (makeHeaders (length body)) ++ headers
8995
conn <- getConn
9096
let req = Request url method allHeaders body
97+
liftIO $ debugM "couchdb.http" $ "Starting " ++ show req
9198
let retry 0 = do
9299
liftIO $ errorM "couchdb.http" $ "request failed: " ++ show req
93100
fail "server error"
@@ -96,7 +103,10 @@ request path query method headers body = do
96103
case response of
97104
Left err -> do
98105
liftIO $ infoM "couchdb.http" $ "request failed; " ++ show n ++
99-
" more tries left: " ++ show req
106+
" more tries left. Error code: " ++ show err ++ ", request: " ++
107+
show req
108+
liftIO $ threadDelay 5000000
109+
reopenConnection
100110
retry (n-1)
101111
Right val -> return val
102112
retry 2
@@ -109,9 +119,11 @@ runCouchDB :: String -- ^hostname
109119
runCouchDB hostname port (CouchMonad m) = do
110120
let uriAuth = URIAuth "" hostname (':':(show port))
111121
let baseURI = URI "http:" (Just uriAuth) "" "" ""
112-
conn <- openTCPPort hostname port
122+
c <- openTCPPort hostname port
123+
conn <- newIORef c
113124
(a,_) <- m (CouchConn conn baseURI hostname port)
114-
close conn
125+
`finally` (do c <- readIORef conn
126+
close c)
115127
return a
116128

117129
-- |Connects to the CouchDB server at localhost:5984.

0 commit comments

Comments
 (0)