This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "snap".

The branch, master has been updated
       via  297f61856bc7d4ab660f6781303a973ee87cdf21 (commit)
      from  25d1c25d8019cb9ed08c074d10b9b46291b42156 (commit)


Summary of changes:
 src/Snap/Extension/Loader/Devel.hs           |    9 +++--
 src/Snap/Extension/Loader/Devel/Evaluator.hs |   51 +++++++++++++++-----------
 2 files changed, 35 insertions(+), 25 deletions(-)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 297f61856bc7d4ab660f6781303a973ee87cdf21
Author: Carl Howells <[email protected]>
Date:   Wed Dec 22 00:34:58 2010 -0800

    Refactor the Evaluator code a bit, to abstract out logic for determining 
when to recompile

diff --git a/src/Snap/Extension/Loader/Devel.hs 
b/src/Snap/Extension/Loader/Devel.hs
index 5332968..0299807 100644
--- a/src/Snap/Extension/Loader/Devel.hs
+++ b/src/Snap/Extension/Loader/Devel.hs
@@ -12,15 +12,14 @@ module Snap.Extension.Loader.Devel
 import           Control.Monad (join)
 
 import           Data.List (groupBy, intercalate, isPrefixOf, nub)
-
 import           Data.Maybe (catMaybes)
+import           Data.Time.Clock (diffUTCTime, getCurrentTime)
 
 import           Language.Haskell.Interpreter hiding (lift, liftIO)
 import           Language.Haskell.Interpreter.Unsafe
 
 import           Language.Haskell.TH
 
-
 import           System.Environment (getArgs)
 
 ------------------------------------------------------------------------------
@@ -138,7 +137,11 @@ hintSnap opts modules initialization handler = do
 
         loader = join $ formatError `fmap` protectHandlers loadInterpreter
 
-    protectedHintEvaluator 3 loader
+        test prevTime = do
+            now <- getCurrentTime
+            return $ diffUTCTime now prevTime < 4
+
+    protectedHintEvaluator getCurrentTime test loader
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Snap/Extension/Loader/Devel/Evaluator.hs 
b/src/Snap/Extension/Loader/Devel/Evaluator.hs
index a10b179..56c8b24 100644
--- a/src/Snap/Extension/Loader/Devel/Evaluator.hs
+++ b/src/Snap/Extension/Loader/Devel/Evaluator.hs
@@ -14,7 +14,6 @@ import Control.Monad.Trans (liftIO)
 import Control.Concurrent (forkIO, myThreadId)
 import Control.Concurrent.MVar
 
-import Data.Time.Clock (NominalDiffTime, diffUTCTime, getCurrentTime)
 import Data.Typeable (Typeable)
 
 import GHC.Prim (Any)
@@ -55,18 +54,21 @@ makeHintInternals init clean exec = HintInternals init' 
clean' exec'
 -- state until the next execution of the input action.  At this time,
 -- the cleanup action will be executed.
 --
--- There will be at least the passed-in 'NominalDiffTime' delay
--- between the finish of one execution of the action the start of the
--- next.  Concurrent calls to the wrapper, and calls within the delay
--- period, end up with the same calculated value returned.
+-- The first two arguments control when recompiles are done.  The
+-- first argument is an action that is executed when compilation
+-- starts.  The second is a function from the result of the first
+-- action to an action that determines whether the value from the
+-- previous compilation is still good.  This abstracts out the
+-- strategy for determining when a cached result is no longer valid.
 --
 -- If an exception is raised during the processing of the action, it
 -- will be thrown to all waiting threads, and for all requests made
 -- before the delay time has expired after the exception was raised.
-protectedHintEvaluator :: NominalDiffTime
+protectedHintEvaluator :: IO a
+                       -> (a -> IO Bool)
                        -> IO HintInternals
                        -> IO (Snap ())
-protectedHintEvaluator minReEval action = do
+protectedHintEvaluator action test getInternals = do
     -- The list of requesters waiting for a result.  Contains the
     -- ThreadId in case of exceptions, and an empty MVar awaiting a
     -- successful result.
@@ -80,7 +82,7 @@ protectedHintEvaluator minReEval action = do
     -- initialization result, or the exception thrown by the
     -- calculation.
     --
-    -- type: MVar (Maybe (Either SomeException (HintInternals, Any), UTCTime))
+    -- type: MVar (Maybe (Either SomeException (HintInternals, Any), a))
     resultContainer <- newMVar Nothing
 
     -- The model used for the above MVars in the returned action is
@@ -88,16 +90,7 @@ protectedHintEvaluator minReEval action = do
     -- one of those MVars is emptied, the next action is to fill that
     -- same MVar.  This makes deadlocking on MVar wait impossible.
     return $ do
-        existingResult <- liftIO $ readMVar resultContainer
-        now <- liftIO getCurrentTime
-
-        (hi, any) <- liftIO $ case existingResult of
-            Just (res, ts) | diffUTCTime now ts < minReEval ->
-                -- There's an existing result, and it's still valid
-                case res of
-                    Right x -> return x
-                    Left  e -> throwIO e
-            _ -> do
+        let waitForNewResult = do
                 -- Need to calculate a new result
                 tid <- myThreadId
                 reader <- newEmptyMVar
@@ -119,8 +112,8 @@ protectedHintEvaluator minReEval action = do
                             previous <- readMVar resultContainer
                             unblock $ cleanup previous
 
-                            -- compile the new action and initialize its state
-                            hi <- unblock action
+                            -- compile the new internals and initialize
+                            hi <- unblock getInternals
                             any <- unblock $ hiInit hi
 
                             let a = (hi, any)
@@ -132,8 +125,8 @@ protectedHintEvaluator minReEval action = do
                             throwIO e
 
                         clearAndNotify r f = do
-                            t <- getCurrentTime
-                            _ <- swapMVar resultContainer $ Just (r, t)
+                            a <- unblock action
+                            _ <- swapMVar resultContainer $ Just (r, a)
                             allReaders <- swapMVar readerContainer []
                             mapM_ f allReaders
 
@@ -143,6 +136,20 @@ protectedHintEvaluator minReEval action = do
                 -- Wait for the evaluation of the action to complete,
                 -- and return its result.
                 takeMVar reader
+
+        existingResult <- liftIO $ readMVar resultContainer
+
+        (hi, any) <- liftIO $ case existingResult of
+            Just (res, a) -> do
+                -- There's an existing result.  Check for validity
+                valid <- test a
+                case (valid, res) of
+                    (True, Right x) -> return x
+                    (True, Left  e) -> throwIO e
+                    (False, _)      -> do
+                        _ <- swapMVar resultContainer Nothing
+                        waitForNewResult
+            Nothing -> waitForNewResult
         hiExec hi any
   where
     cleanup (Just (Right (hi, any), _)) = hiClean hi any
-----------------------------------------------------------------------


hooks/post-receive
-- 
snap
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap

Reply via email to