May 16, 2010
I announced on the web-devel list that Yesod 0.2 is basically feature complete, and almost ready for release. I decided to finally go and do some maintenance on some of the underlying libraries, so I wanted to give some updates. Some of this is stuff I've been itching to do for a while, so I'm pretty excited it will be included for Yesod 0.2.
The one big weak link in the enumerator chain for WAI has been the GZIP middleware; it was originally based on the standard zlib package on Hackage, which uses lazy I/O. In essence, we were losing a lot of the benefits of the WAI whenever we compressed output.
But not anymore! I've released wai-extra 0.1.1, which includes an enumerator-based binding to the zlib library.
The new wai-extra 0.1 series is designed to minimize external dependencies. I dropped the clientsession and methodoverride middlewares (I don't think they'll be missed), and drop dependencies on a few other packages. I believe the only non-Haskell Platform packages are now sendfile and wai, and clearly the latter has to stay in.
As a future roadmap, I'm considering porting over the encoding functions in web-encodings and specializing them for datatypes in WAI. For example, decodeUrlPairs would only work on strict bytestrings, since that's how WAI provides the query string.
I originally wrote hack-handler-fastcgi as a port of the fastcgi package on Hackage, which in turn wraps the C library. I was very excited when Dan Knapp released direct-fastcgi, and recently I wrote a wrapper around it that allows you to run your WAI applications with it. I'm using it in production with lighttpd for my most recent client site.
One little annoyance: there's a debugging line that outputs "fromList " for every request. I emailed Dan about this, and hopefully he'll remove it; in the meanwhile, for version 184.108.40.206, you can just remove line 1704 in Network/FastCGI.hs.
With some help from Anton Ageev, yaml, data-object-yaml and data-object-json all got a bit of an update, including some iteratee goodness. I won't repeat myself: you can read the release announcement.
failure et al
The failure package got bumped to 0.1.0. The only real change was renaming MonadFailure to Failure. This created a cascade of releases for control-monad-failure, attempt, safe-failure, control-monad-attempt, etc.
This package makes failure handling very nice, I encourage people to look into it.
And now a bit of a wart. I really didn't like having the Crypto dependency, since it takes forever to build all the tests, especially on a low-memory server. I e-mailed them a patch to make the tests optional, but it hasn't been applied. On top of that, I have a feeling that the AES implementation in Crypto is very inefficient, since it deals directly with lists of Word8s.
I tried switching over to SimpleAES. In fact, I even released clientsession 0.3.0 based on SimpleAES. However, it seems there's some bug for 32-bit systems (my server again). I traced it down to something in assembly, at which point I gave up.
My next step was to try pulling the AES code into the clientsession repo to avoid the test building, but that still runs very slowly.
So I just wrote some code in a separate branch that uses incredibly fast XOR encryption. Combined with some compression to avoid frequency analysis, this may be enough, but I definitely want a more robust solution in place by release.
And by popular demand, I've ported bloggy to Yesod 0.2. I personally don't think it's a great way to learn Yesod- I believe the tutorials give a better view without clouding the scene with data serialization issues- but for those who want it, it's available.
I won't even consider releasing Yesod until I can go a few days without making a breaking API change. I'm still finding minor things all over the place where a change is nice, and I'd rather have a solid release than an earlier one.
Also, my next project is massively database-driven, so I'm already thinking hard about the next Yesod release. Here's the thoughts I've been tossing around, very much unpolished:
- Define entities but not entity relationships. Allow entities to hold references to other entities (ie, keys). And the layer will use no joining at all.
- Create a Query datatype somehow, and values will be created using combinators like
filterBy someField myValueor
- Have some typeclass for converting a Query into various monads.
As I said, very unpolished... and it's late... hopefully better stuff tomorrow.