@@ -11,17 +11,20 @@ module Database.CouchDB.HTTP
1111 , runCouchDB'
1212 ) where
1313
14+ import Data.IORef
15+ import Control.Concurrent
1416import System.Log.Logger (errorM ,debugM ,infoM )
1517import Network.TCP
1618import Network.Stream
1719import Network.HTTP
1820import Network.URI
21+ import Control.Exception (finally )
1922import Control.Monad.Trans (MonadIO (.. ))
2023
2124-- | Describes a connection to a CouchDB database. This type is
2225-- encapsulated by 'CouchMonad'.
2326data 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
6265getConn :: 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
6570reopenConnection :: CouchMonad ()
6671reopenConnection = 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
7177makeHeaders 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
109119runCouchDB 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