static: fix the build on GHC 7.4

There were two build issues on GHC 7.4: using atomicModifyIORef'
and ByteString.Lazy.toStrict, both of which were missing.  These
are now fixed.

In addition, looking at the IORef code more closely,
we want the quite a bit of strictness in the IORef.
The common case is that the widget content already exists in the map
(every reload of a page will call embedStaticContent), but until we
force the map the thunks holding the duplicated generated content will
be kept around, leaking memory.  This will be the common situation since
the vast majority of the time the content already exists.  Since
the containers module does not have a strict map until 0.5, use
unordered containers which does have a strict map.
This commit is contained in:
John Lenz 2013-09-12 17:52:15 -05:00
parent 8e16fd2227
commit 1a5aa23f13
4 changed files with 19 additions and 5 deletions

View File

@ -67,7 +67,7 @@ import Yesod.Core.Types
)
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
import qualified Data.Map as M
import qualified Data.HashMap.Strict as M
import qualified WaiAppStatic.Storage.Embedded as Static
import Yesod.EmbeddedStatic.Types

View File

@ -3,6 +3,7 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE CPP #-}
module Yesod.EmbeddedStatic.Internal (
EmbeddedStatic(..)
, Route(..)
@ -34,16 +35,26 @@ import Yesod.Core
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Map as M
import qualified Data.HashMap.Strict as M
import qualified WaiAppStatic.Storage.Embedded as Static
import Yesod.Static (base64md5)
import Yesod.EmbeddedStatic.Types
#if !MIN_VERSION_base(4,6,0)
-- copied from base
atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
atomicModifyIORef' ref f = do
b <- atomicModifyIORef ref
(\x -> let (a, b) = f x
in (a, a `seq` b))
b `seq` return b
#endif
-- | The subsite for the embedded static file server.
data EmbeddedStatic = EmbeddedStatic {
stApp :: !Application
, widgetFiles :: !(IORef (M.Map T.Text File))
, widgetFiles :: !(IORef (M.HashMap T.Text File))
}
instance RenderRoute EmbeddedStatic where

View File

@ -15,7 +15,8 @@ import Yesod.EmbeddedStatic
import Yesod.Test
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL
mkEmbeddedStatic False "eProduction" [testGen]
@ -110,7 +111,7 @@ embedProductionSpecs = yesodSpec (MyApp eProduction) $ do
[script] <- htmlQuery "script"
let src = BL.takeWhile (/= 34) $ BL.drop 1 $ BL.dropWhile (/= 34) script -- 34 is "
get $ T.decodeUtf8 $ BL.toStrict src
get $ TL.toStrict $ TL.decodeUtf8 src
statusIs 200
hasCacheControl
assertHeader "Content-Type" "application/javascript"

View File

@ -52,6 +52,7 @@ library
, process-conduit >= 1.0 && < 1.1
, filepath >= 1.3
, resourcet >= 0.4
, unordered-containers >= 0.2
exposed-modules: Yesod.Static
Yesod.EmbeddedStatic
@ -101,6 +102,7 @@ test-suite tests
, process-conduit
, filepath
, resourcet
, unordered-containers
ghc-options: -Wall