1
0
forked from GitHub/gf-core

Multithreaded gf.fcgi.

This commit is contained in:
bjorn
2008-10-16 13:00:44 +00:00
parent bc87219f8e
commit e94cfd8567
3 changed files with 28 additions and 21 deletions

View File

@@ -104,21 +104,26 @@ restartIfModified =
-- Utilities for getting and caching read-only data from disk.
-- The data is reloaded when the file on disk has been modified.
type DataRef a = IORef (Maybe (ClockTime, a))
data DataRef a = DataRef {
dataFile :: FilePath,
dataLoad :: FilePath -> IO a,
dataValue :: MVar (ClockTime, a)
}
newDataRef :: MonadIO m => m (DataRef a)
newDataRef = liftIO $ newIORef Nothing
newDataRef :: (FilePath -> IO a) -> FilePath -> IO (DataRef a)
newDataRef load file =
do t <- getModificationTime file
x <- load file
v <- newMVar (t,x)
return $ DataRef { dataFile = file, dataLoad = load, dataValue = v }
getData :: MonadIO m => (FilePath -> m a) -> DataRef a -> FilePath -> m a
getData loadData ref file =
do t' <- liftIO $ getModificationTime file
m <- liftIO $ readIORef ref
case m of
Just (t,x) | t' == t -> return x
_ -> do logCGI $ "Loading " ++ show file ++ "..."
x <- loadData file
liftIO $ writeIORef ref (Just (t',x))
return x
getData :: DataRef a -> IO a
getData ref =
do t' <- getModificationTime (dataFile ref)
(t,x) <- takeMVar (dataValue ref)
x' <- if t' == t then return x else (dataLoad ref) (dataFile ref)
putMVar (dataValue ref) (t',x')
return x'
-- Logging

View File

@@ -5,28 +5,29 @@ import qualified PGF
import FastCGIUtils
import URLEncoding
import Network.CGI
import Network.FastCGI
import Text.JSON
import qualified Codec.Binary.UTF8.String as UTF8 (encodeString, decodeString)
import Control.Concurrent
import Control.Monad
import Data.Char
import qualified Data.Map as Map
import Data.Maybe
import System.Environment
grammarFile :: FilePath
grammarFile = "grammar.pgf"
grammarFile :: IO FilePath
grammarFile = do env <- getEnvironment
return $ fromMaybe "grammar.pgf" $ lookup "PGF_FILE" env
main :: IO ()
main = do initFastCGI
r <- newDataRef
loopFastCGI (handleErrors (handleCGIErrors (fcgiMain r)))
ref <- grammarFile >>= newDataRef PGF.readPGF
runFastCGIConcurrent' forkIO 100 (handleErrors (handleCGIErrors (fcgiMain ref)))
fcgiMain :: DataRef PGF -> CGI CGIResult
fcgiMain ref = getData (liftIO . PGF.readPGF) ref grammarFile >>= cgiMain
fcgiMain ref = liftIO (getData ref) >>= cgiMain
cgiMain :: PGF -> CGI CGIResult
cgiMain pgf =

View File

@@ -20,3 +20,4 @@ executable gf.fcgi
main-is: MainFastCGI.hs
other-modules:
FastCGIUtils
ghc-options: -threaded