Archive for July, 2009

Embedding files in a binary

July 23, 2009

So this time, I’m asking for community input.

Problem

So, if you’ve been paying attention to the flow of the packages I’ve written, you might see a direction: write a web application, and let it run as a standalone application. However, what do you do about static files (CSS, JavaScript, etc)?

Solution 1: Install static files in a standard location

This is pretty straight forward, and seems to be a well-accepted practice for lots of types of files. For example, I think it’s recommended for Glade files. However, I have always felt a little awkward about it.

Solution 2: Embed the files in the binary

Overall, this has the benefit of allowing the binary to just be moved around without regard for the static files. That’s my main goal in this. It has a side benefit of minimizing file system access, which for my purposes is not that important. On the downside, it makes it more difficult to make changes (eg, a full recompile to change from blue to green).

I see two ways of accomplishing this.

Solution 2a: Code generator

Have a little utility that takes a file, and converts it to a Haskell file containing the file contents. Disadvantage: an extra step in the compile process. Advantage: you can make a dependency from foo-bar.txt to foo-bar_txt.hs so that your build program knows to automatically regenerate the files.

Solution 2b: Template Haskell

Advantage: simplicity. Disadvantage: you’ll need to touch your Haskell file each time you make a static file change.

I’ve implemented a simple version of this. It exports two functions: one for including a single file, one for an entire directory tree. The code is available on Github. I haven’t uploaded it to Hackage. This is my first stab at Template Haskell, so if you see any glaring mistakes please let me know.

Also, if people have any suggestions on which solution is best, or know of a different solution to this issue, please let me know!

Advertisements

hack-handler-webkit

July 8, 2009

So I had the idea the other day to make it possible to turn Hack web applications into standalone GUIs. I prefer writing web apps to desktop apps with, for example, GTK, so being able to run arbitrary web apps as if they are simply desktop ones would be a big boon for me. Plus, it means you can live the dream of writing an application once and having it run client-server and locally.

I ripped off the sample for the GTK Webkit port, removed some of the features (I decided I didn’t want back/forward buttons or an address bar), wrote some FFI code, combined it all with hack-handler-simpleserver, and created hack-handler-webkit.

Caveats:

  • The code is not incredibly beautiful, especially since I’ve never written FFI code before (hack-handler-fastcgi was just a ripoff of the original fastcgi package).
  • I’ve only tested it on Ubuntu Jaunty. It doesn’t really do much checking, just uses pkg-config to check for the existence of the webkit-1.0 package. I doubt this will work for other distributions.
  • As stated above, it uses the GTK port. I would like to get this working for Windows and Mac as well, without using the GTK port. If anyone would like to fork this on github and add that functionality, it would be much appreciated.

If you’re running Ubuntu and wanted to give this a try, do the following:

  1. apt-get the correct stuff. I think you’ll just need libwebkit-dev (ie, apt-get install libwebkit-dev).
  2. Download hack-handler-webkit from github and install it. It’s not an hackage yet for obvious reasons.
  3. I branched the hack-samples package I spoke about last week to use this webkit backend. Go ahead and try that out.

Comments, suggestions and bug reports are much appreciated!

Hack sample- chat server

July 1, 2009

Not that you’ll want to replace IRC with this any time soon, but I’ve put together an incredibly simplistic chat server to demonstrate Hack. The code is available in my hack-samples github repo. I’m not going to copy the source code here, but point out a few cool pieces.

In the imports list, I say import qualified Hack.Handler.SimpleServer as Handler to use the SimpleServer handler. Later on, I use Handler.run 3000 to run a simple server on port 3000. If you instead replace SimpleServer with CGI and remove the 3000, you immediately have a CGI application. Of course, all of the MVar concurrency code is unneeded overhead in a CGI application, but you could also use Happstack, FastCGI or any other handler.

Also, I alluded in my previous post to the idea of using currying to initiate some stuff. This code is a perfect example. In my main function, I load up data from a text file, create a Handle to write to, wrap them both in MVars and use that to curry the app function. This way, all of that initialization code only gets called once, no matter how many requests are served. This is a simple approach which works very well in production.

Not much more to say, I think the code speaks for itself!