<div dir="ltr">Hi all,<div><br></div><div>I think it&#39;s no secret that wai-handler-devel is not living up to its full potential. Here&#39;s a few of the issues that I know about:</div><div><br></div><div>* Doesn&#39;t integrate well with cabal-dev. (Fair warning: I haven&#39;t yet started using cabal-dev.)</div>


<div>* It reinterprets the entire application, instead of just the files that changed and their dependencies.</div><div>* It has no knowledge of your cabal file, and so simply tries to use the most recent version of each package available. A few people this week noticed problems running wai-handler-devel since WAI 0.4 was released but is not yet supported by Yesod.</div>

<div><br></div><div>Some of these issues can be solved while still sticking with Hint. However, that will require reimplementing a significant amount of work that already exists in other places. I think our best bet is to re-evaluate entirely what we need, and think about the best way to get there. Let&#39;s start by pointing out why &quot;cabal build &amp;&amp; ./dist/build/myapp/myapp&quot; isn&#39;t good enough:</div>

<div><br></div><div>* Linking an executable is *very* slow.</div><div>* You have to manually kill your application and rerun the above command each time you change a file.</div><div>* If an external file included by Template Haskell, such as a Hamlet template, is modified, cabal does not know to recompile that module.</div>

<div><br></div><div>But the fact is that the simple cabal build approach *does* solve all of the issues we currently have with wai-handler-devel. (Well, at least the three I mention above, feel free to chime in here.) So here&#39;s an idea: let&#39;s try to build on top of cabal so we can take advantage of its features. As for the points listed above, I&#39;ll address them in reverse order.</div>

<div><br></div><div>wai-handler-devel already contains code that determines which &quot;extra&quot; files are actually dependencies for a module. For example, it looks for hamletFile through your source code and, when it finds it, notes that the specified file is a dependency. We can easily write a tool that checks the timestamps on all the files, determines if a file needs to be updated, and modifies timestamps accordingly. For example, if Handler/Root.hs uses hamlet/root.hamlet, and the latter has a newer modification date than the former, the tool would change the former&#39;s modification date to the same as the latter.</div>

<div><br></div><div>As far as manually killing applications and rerunning the compile steps, that&#39;s also very simple: we simply have a monitor program that sees if source files have been modified since the last build. wai-handler-devel already does this. We can optimize this on Linux with inotify, and the equivalent on other operating systems, but I think it&#39;s fair to say that this is a solved problem.</div>

<div><br></div><div>The big question is how to avoid long links. The simple answer is to skip them: we don&#39;t actually need an executable, just the object files. We&#39;ll then use plugins[1] to hot-load the code... except that plugins seems to be (1) buggy and (2) not cross-platform. We can try out direct-plugins[2] instead, but it seems that it will require us to install the package into GHC&#39;s database, which isn&#39;t necessarily a good idea. (Perhaps we can ask Dan very nicely to make some API changes to help us here?) The third route is writing the hot-loading code ourselves. Andy Stewart pointed out to me that manatee[3] does this directly against the GHC API.</div>

<div><br></div><div>My guess: our best bet is to ask Dan (direct-plugins&#39;s author) to work with us on augmenting his package with the features we need. This can have ramifications outside the realm of wai-handler-devel, such as having a server that hot-loads code for individual applications. (I was thinking of this for Lambda Engine actually.) But before starting down that route, I&#39;d love to hear if others have any opinions on the subject.</div>

<div><br></div><div>Sorry for the long email :)</div><div><br></div><div>Michael</div><div><br></div><div>[1] <a href="http://hackage.haskell.org/package/plugins">http://hackage.haskell.org/package/plugins</a></div><div>
[2] <a href="http://hackage.haskell.org/package/direct-plugins">http://hackage.haskell.org/package/direct-plugins</a></div>
<div>[3] <a href="http://hackage.haskell.org/package/manatee">http://hackage.haskell.org/package/manatee</a></div><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta http-equiv="content-type" content="text/html; charset=utf-8"></div>