Rapi: fully evaluate the body in getUrl
authorIustin Pop <iustin@google.com>
Wed, 5 Jan 2011 10:27:02 +0000 (11:27 +0100)
committerIustin Pop <iustin@google.com>
Fri, 7 Jan 2011 15:39:37 +0000 (16:39 +0100)
Currently, the Rapi.getUrl function returns the body without
evaluating it, and the other functions (loadData, parseData) do the
same. In effect, the top-level structure returned from loadData can be
a thunk which depends on the curl operation, thus keeping the curl
resources alive even after return from the Rapi module.

While this is not a problem in single-threaded programs, it can become
an issue with the threaded runtime. So it's better to fully evaluate
the HTTP body before returning from the getUrl function, so that at
least the curl resources are released.

Either "return $! body" or "(code, !body) <- …" works (i.e. avoids the
segfaults in my tests), but I think it's cleaner to force full
evaluation of the body when returning from the curlGetString
function. For this, we also enable the BangPatterns language
extension.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Balazs Lecz <leczb@google.com>

Ganeti/HTools/Rapi.hs

index 28bfe89..ac0fd96 100644 (file)
@@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 -}
 
+{-# LANGUAGE BangPatterns #-}
+
 module Ganeti.HTools.Rapi
     (
       loadData
@@ -55,7 +57,7 @@ curlOpts = [ CurlSSLVerifyPeer False
 -- | Read an URL via curl and return the body if successful.
 getUrl :: (Monad m) => String -> IO (m String)
 getUrl url = do
-  (code, body) <- curlGetString url curlOpts
+  (code, !body) <- curlGetString url curlOpts
   return (case code of
             CurlOK -> return body
             _ -> fail $ printf "Curl error for '%s', error %s"