Dynamic Source Loading

I am writing a web application server in Haskell. I would like to be able to modify the app on the fly. Simplyfing the app server, it would look like this: appServer appMVar reqChan state = do req <- readChan reqChan app <- readMVar appMVar (state',resp) <- return $ app state req forkIO $ doResp req resp appServer appMVar reqChan state' The app would get loaded as follows: updateApp writeLog appMVar moduleName fnName = do mbApp <- (getApp >>= Just) `catch` (\err -> writeLog err >> return Nothing) maybe (return ()) (overWriteMVar appMVar) mbApp threadDelay 1000 updateApp appMVar moduleName fnName where getApp = ghci_load_module moduleName >>= flip ghci_getName fnName overWriteMVar mvar val = if isEmptyMVar appMVar then putMVar appMVar app else swapMVar appMVar app {-- Is there a way to overwrite an MVar without risking blocking by another thread filling it before the putMVar? Note it would be really nice if: * ghci_load_module would use an already cached module if the underlying source file has not changed (and therefore cost little performance-wise). * the returned code would be compiled with lots of optimization, etc. * Bonus: it would verify that the loaded function is type consistent with channel but tolerate bigger data types so that if the prior app assumed state was data State = Foo | Bar It would not be an error if the new app handled a state that looked like: data State = Foo | Bar | Baz The result would be a haskell server where all the haskell source acts like asp, jsp, php pages, but its all type safe and you don't have to define a standard page type as in HSP. I am aware that there is a DynamicLoader project: http://www.dtek.chalmers.se/~d00ram/dynamic/ That lets you load "object files." But I would really like something that loads source files instead.... Is this possible? -Alex- ______________________________________________________________ S. Alexander Jacobson tel:917-770-6565 http://alexjacobson.com

haskell:
I am writing a web application server in Haskell. I would like to be able to modify the app on the fly. Simplyfing the app server, it would look like this:
appServer appMVar reqChan state = do req <- readChan reqChan app <- readMVar appMVar (state',resp) <- return $ app state req forkIO $ doResp req resp appServer appMVar reqChan state'
The app would get loaded as follows:
updateApp writeLog appMVar moduleName fnName = do mbApp <- (getApp >>= Just) `catch` (\err -> writeLog err >> return Nothing) maybe (return ()) (overWriteMVar appMVar) mbApp threadDelay 1000 updateApp appMVar moduleName fnName where getApp = ghci_load_module moduleName >>= flip ghci_getName fnName
overWriteMVar mvar val = if isEmptyMVar appMVar then putMVar appMVar app else swapMVar appMVar app {-- Is there a way to overwrite an MVar without risking blocking by another thread filling it before the putMVar?
Note it would be really nice if:
* ghci_load_module would use an already cached module if the underlying source file has not changed (and therefore cost little performance-wise).
* the returned code would be compiled with lots of optimization, etc.
* Bonus: it would verify that the loaded function is type consistent with channel but tolerate bigger data types so that if the prior app assumed state was
data State = Foo | Bar
It would not be an error if the new app handled a state that looked like:
data State = Foo | Bar | Baz
The result would be a haskell server where all the haskell source acts like asp, jsp, php pages, but its all type safe and you don't have to define a standard page type as in HSP.
I am aware that there is a DynamicLoader project:
http://www.dtek.chalmers.se/~d00ram/dynamic/
That lets you load "object files." But I would really like something that loads source files instead....
Please look at hs-plugins: http://www.cse.unsw.edu.au/~dons/hs-plugins and the accompanying paper: http://www.cse.unsw.edu.au/~dons/hs-plugins/paper hs-plugins is already being used at Chalmers for their Haskell Server Pages project, which sounds a lot like what you're describing. You can ask Niklas Broberg about this. Cheers, Don

Please look at hs-plugins: http://www.cse.unsw.edu.au/~dons/hs-plugins
and the accompanying paper: http://www.cse.unsw.edu.au/~dons/hs-plugins/paper
hs-plugins is already being used at Chalmers for their Haskell Server Pages project, which sounds a lot like what you're describing. You can ask Niklas Broberg about this.
Indeed, we have a working server that does runtime loading of HSP pages (i.e. Haskell apps) using hs-plugins. We'll be releasing a first version some time really soon, but if you want a preview just send me a mail. =) /Niklas

"S. Alexander Jacobson"
That lets you load "object files." But I would really like something that loads source files instead....
http://www.cse.unsw.edu.au/~dons/hs-plugins/index.html hs-plugins can build and load source, and check dependencies, and lots more. Also, check out hws-wp that's a modified version of Simon Marlow's web server that includes an apache-style plugin framework. In my opinion, you can steal a lot of the ideas there or just hack hws-wp to use hs-plugins. You'll probably want to use Don's recent strategy of dynloading everything on a tiny static core, otherwise you'll run across incomparable values where the static and dynamic type tables don't mesh. David Himmelstrup has been profiling Halipeto recently. I think a combination of Halipeto and either WASH-CGI or HaXML would work nicely. Add HaskellDB for sane database access, and you've nearly surpassed J2EE for features. I heard rumors that the HaskellDB guys are massaging HaskellDB to work with hs-plugins too. For other useful web application server features, Björn Bringert's XmlRpc library is nice. -- Shae Matijs Erisson - Programmer - http://www.ScannedInAvian.org/ "I will, as we say in rock 'n' roll, run until the wheels come off, because I love what I do." -- David Crosby
participants (4)
-
dons@cse.unsw.edu.au
-
Niklas Broberg
-
S. Alexander Jacobson
-
Shae Matijs Erisson