That said, I would like to focus on narrowing the scope of the project
a bit more and drive towards a common goal.
What is Happstack at this point in the road? Here are some of the
parts of the puzzle:
- a fairly mature http application server
- a fairly immature frontend http server (ipv6 and file serving -- to
name a couple of the areas of weakness)
- a fairly immature prevayler style persistence layer (lack of tools
and learning curve are a couple of issues here)
- a mixed bag of mature and immature utility functions of which some
are slowly decaying (in terms of maintenance)
Each of these four aspects could easily be a full-time job for one developer
Some open questions to the community:
1. How valuable do you find each of these pieces to be in your work
(whether it be personal or professional)?
2. What do you see as the main weakness of the current implementation
and/or community?
3. Which items could be potentially taken away to ease the overall
code footprint with minimal impact and/or which items really belong in
a separate project alltogether (state anyone?).
Regards,
Matthew Elder
--
Sent from my mobile device
Need somewhere to put your code? http://patch-tag.com
Want to build a webapp? http://happstack.com
> Each of these four aspects could easily be a full-time job for one developer
>
> Some open questions to the community:
>
> 1. How valuable do you find each of these pieces to be in your work
> (whether it be personal or professional)?
Greetings from Budapest! (I'm on my honeymoon here).
If I were to evaluate how important the various happstack pieces are to
me:
* HTTP application server -- absolutely critical, the raison d'etre for
the package, and the part of it I'm actually using, both for personal
projects and at work -- but it needs an extensive overhaul and maybe a
re-architecting (as we've discussed)
* HTTP frontend server -- also critical for similar reasons, but the
current implementation is not so hot and should be replaced by
something better.
* Persistence layer -- I'm completely disinterested and will remain so
until the design and code documentation reaches an acceptable level of
quality. Right now I have no idea how it actually *works* because it's
far too complicated and under-documented. I also have some pretty deep
reservations about its performance/overhead/scalability
characteristics. Has anyone done a comprehensive benchmark/performance
evaluation? I've heard apocryphal stories of it gobbling tons of RAM.
* Utility functions -- should probably be packages in their own right if
they're self-contained enough, "kitchen-sink"-type libraries are a sure
sign of questionable design decisions.
> 2. What do you see as the main weakness of the current implementation
> and/or community?
Lazy I/O in the HTTP protocol handler, this has bitten me in the ass
with unpredictable performance characteristics several times.
Community-wise things are fine, I've felt no obstacles to stepping in
and contributing. I wish for a better wiki/bug-tracker though. (Trac?)
We should also be supplying better-written, cleaner, more
aesthetically-pleasing tutorial material.
> 3. Which items could be potentially taken away to ease the overall
> code footprint with minimal impact and/or which items really belong in
> a separate project alltogether (state anyone?).
I think I know where you're going with this. It's my position that the
question of persistence/data layer should be orthogonal to the HTTP
application server stuff, and any effort to entwine them further should
be resisted. Happstack should be usable without the state portion.
I know for a fact that there are people who feel exactly the opposite
way, and wish for Happstack to be a Rails-ish HTTP/user
management/data-layer/ORM/templating megalith. So you're right that we
need to develop a consensus on the direction of the project.
***
As a thought experiment, let's enumerate a cople of different projects
we could be working on:
* A rewrite of the base-level HTTP application server stuff. The
ServerPartT transformer stack is pretty cool and has some great
features but is overcomplicated, exposes too much of its internals in
the public interface, and has problems re: lazy I/O. To me this one is
a sine qua non for any further work, we need a more solid foundation
to build upon. I'm planning on working on this at Hac Phi, by the end
of that weekend we should have a candidate replacement for the old
stuff along with some kind of a compatibility layer for ServerPartT to
avoid breaking old code.
* An implementation of sharding for happstack-state -- lots of people
have asked about this, being unable to scale beyond 4GB datasets is an
unreasonably severe limitation.
* An implementation of happstack-state based on secondary storage
(i.e. not 100% in RAM) -- see above -- no idea how this might work.
* Some useful Rails-ish utility modules for building real-world
web-apps; user management, model-view-controller crud, built-in
Javascript stuff, etc.. I'm definitely not keen on moving in an
explicitly "Ruby-on-Rails-clone" direction, Haskell isn't like Ruby
and I think we can definitely do better.
In my mind we would need some design consensus re: how all that stuff
wold plug together before we can proceed on that front. My feeling is
that the natural way to do pluggable componentry in Haskell is via
typeclasses: for example, to do user management you'd make your
toplevel website monad implement a "UserManager" typeclass that would
provide the operations you need, probably by wrapping some common
authentication code.
Keeping the interface separate from the implementation would allow you
to plug in different user auth modules depending on which design
decisions make sense for your problem domain, i.e. challenge-response
vs. plaintext/SSL, MySQL vs. happstack-state vs. Tokyo Tyrant, MD5 vs
SHA, web browsers/cookies vs. middleware/SOAP, etc.
***
Hope this provides some fodder for conversation.
G
--
Gregory Collins <gr...@gregorycollins.net>
* HTTP application server: Critical
I think web services should be Happstack's primary focus.
* HTTP front end server: Critical
I think it should be important to be able to make Happstack serve as
either a front end OR a back end.
* Persistence layer: Important
I love the idea of primary storage being in RAM. I would rather
blacklist certain kinds of data from cache (RAM) than whitelist
certain kinds of data (from disk) for cache. That said, we don't
have a very easy way to do that yet.
* Utility functions: Not Important
Such things should definitely be put into separate libraries.
> 2. What do you see as the main weakness of the current implementation
> and/or community?
Too much Template Haskell in State. The TH makes it extremely hard to
follow and understand. If it's too complex without the TH, we should
probably address that, not hide it.
State also should provide some way to optionally remove some data from
RAM, retrieving it from disk as needed. For example, I believe the
current way to upload and save large files to a Happstack application is
to simply save them to disk and file serve them. It would be excellent
to be able to store these along with other associated data in State, but
only load them into memory on demand. This can be extrapolated into any
infrequently accessed data, however large or small, of course.
Sharding will be great once it's working properly, but I honestly think
that proper optimization for the resources available to you on a single
system is the best way to go at first. Note that I am not advocating the
traditional way of storing data on the hard drive only and caching in
memory as needed. Rather, I'm advocating storing data primarily in
memory but making exceptions for some data to store only on the hard
drive (and perhaps later in the development of State even automatically
caching some of the most frequently read data in memory, as is traditional).
> 3. Which items could be potentially taken away to ease the overall
> code footprint with minimal impact and/or which items really belong in
> a separate project alltogether (state anyone?).
I think nearly every component should be as loosely coupled and
separated as possible. New packages can then be created to tie things
together if the Railsy types want that sort of thing, but I would rather
the core be highly modular. State, Ix, and many of the utilities can be
separated pretty cleanly. I honestly don't even understand why
happstack-util exists, as it's components have very little to do with
Happstack proper or each other. The happstack package's dependencies
ideally shouldn't even have "happstack" in their names, although that
would be overly pedantic. In my opinion, the core of Happstack is the
server, so happstack-server should be the new happstack, and the current
happstack package should cease to exist. Other pieces can be added as
needed.
- Jake
I use the application server and HTTP server in gitit. I don't use
happstack-state at all, mostly because of the complexity and the
difficulty managing migrations. I think it is important that
happstack-server be made orthogonal to happstack-state -- but that
has mostly been achieved in happstack-0.2.
> 2. What do you see as the main weakness of the current implementation
> and/or community?
happstack-0.2 is a huge improvement over the original HAppS. I'd like to
see happstack-0.3 released as soon as possible, since it fixes a serious
memory leak (among other things). But the community seems great -- I
hope momentum can be kept up.
John
> State also should provide some way to optionally remove some data from
> RAM, retrieving it from disk as needed.
I've been thinking about this idea as well. I think it could be
useful, although it won't solve the scaling problems I mentioned
earlier.
Personally i think that this idea that everything has to be in RAM
does not make any economical sense, maybe only for very few specific
applications.
Now, being able to store data based on your language's data type, that
is a really good idea.
My 2 cents.
Flavio Botelho
For the record, neither HAppS nor Happstack force the user to use our
data storage.
> 1. Remove data storage into separate project.
...
> happs has is the incredibly high entry barrier. Make it simple to
> start writing stateful web applications with it.
These two items seem to be in conflict.
I don't think this attitude of "don't do it yourself" will result in
new, useful, interesting models.
> Happstack should be only about web server and apllication server.
>
> 1. Remove data storage into separate project.
Agreed.
> 2. Get rid of Template Haskell from end user code. If you need to use
> it inside the project, it is perfectly fine. But to demand from end
> user (often beginner haskell programmer) to learn and maintain another
> level of complexity - is too much.
Agreed, mostly.
> 3. Please implement sessions that are a: not based on your data
> storage, b: do not require Template Haskell wizardry.
This does not sound like it should be in the scope of the Happstack
project, proper. It sounds more like a utility, which implies it should
be in a separate package.
- Jake
Unfortunately I don't think it's easy to have a simple state system in
an inherently multithreaded program written in a pure functional
language. That said, I do think happstack-state could be a lot
simpler. Why don't we just use STM and have people write their own
savers for data?
--
shu
Guaranteeing data integrity with reasonable efficiency constrains
isn't as trivial as that, I'm afraid.
--
Cheers,
Lemmih
Err, I meant data persistency, not data integrity.
--
Cheers,
Lemmih
> So my interest in happs and now happstack is in using it for the
> hackage server. The main reason I chose happs (and then worked on it
> with Lemmih) over other frameworks is because of the persistence layer
> (meaning we can use Haskell types)...
> Splitting things up is fine. Please don't deprecate or abandon the
> state system. It's really the most interesting bit.
I'm just a lurker who has hardly used happstack nor contributed to it
but I want to second this. What make happstack really interesting and
unique is IMO the persistence model and (promise of) multimaster and
sharding. Those are the main reason I'm lurking here and, I contend,
the reason happs[tack] has garnered some interest outside of the
Haskell community.
Thanks,
Bjorn
> deriving instance Show OrderId > deriving instance Eq OrderId > deriving instance Ord OrderId > deriving instance Typeable OrderId > instance Version OrderId > $(deriveSerialize ''OrderId)The point of my last mail is that recent GHC probably lets you fold all of these declarations into mkMethods.
I think this is a good idea, kudos to Thomas Hartman for bringing it
up. I would contribute a modest amount (<$100) toward improving
state/multimaster/sharding (code and documentation). I don't use
happstack but would like to see these things working and working well!
Thanks,
Bjorn
> How many followers of this NG are interested in HAppS for building
> commercial facing web 2.0 type apps, and how many are interested in
> HAppS for other reasons? (In house apps, web services, etc).
For me the answer is "both".
> Before working on allowing HAppS to handle larger data sets
> (sharding), it makes sense to make sure it handles existing data sets
> extremely reliably. Amazon has provided a lot of the server plumbing
> required to make this job simpler. We can generalize to other
> platforms in the future, but we might as well take advantage of what
> Amazon provides now (perhaps becoming the standard operating system
> there).
Having Amazon facilities plug into happstack might be cool but please,
only as an optional dependency. We use Amazon at work but I really don't
want to be "married" to it.
> Once multimaster is really bulletproof, it may make sense to do
> sharding. Until we have automated sharding, the solution for those
> concerned is manual sharding. The correct approach to this depends on
> your application, but a simple approach that works for most cases is a
> directory server that maps object IDs to the server that hosts it. At
> 128 bits per entry, it is highly unlikely that you will have enough
> objects to exceed 4GB.
The directory server then becomes another scaling bottleneck, and you'd
*need* multimaster/hot-swap to make sure that a failure of your
dictionary server didn't take down the other cluster.
Another approach you might consider is consistent hashing.
Alex Jacobson <al...@alexjacobson.com> writes:Before working on allowing HAppS to handle larger data sets (sharding), it makes sense to make sure it handles existing data sets extremely reliably. Amazon has provided a lot of the server plumbing required to make this job simpler. We can generalize to other platforms in the future, but we might as well take advantage of what Amazon provides now (perhaps becoming the standard operating system there).Having Amazon facilities plug into happstack might be cool but please, only as an optional dependency. We use Amazon at work but I really don't want to be "married" to it.
Once multimaster is really bulletproof, it may make sense to do sharding. Until we have automated sharding, the solution for those concerned is manual sharding. The correct approach to this depends on your application, but a simple approach that works for most cases is a directory server that maps object IDs to the server that hosts it. At 128 bits per entry, it is highly unlikely that you will have enough objects to exceed 4GB.The directory server then becomes another scaling bottleneck, and you'd *need* multimaster/hot-swap to make sure that a failure of your dictionary server didn't take down the other cluster.
Another approach you might consider is consistent hashing.
2. What do you see as the main weakness of the current implementation and/or community?I've got no real complaints at the moment. Lack of decent http authentication is a bit of a pain.
Splitting things up is fine. Please don't deprecate or abandon the state system. It's really the most interesting bit. I appreciate everything in-memory doesn't work for every application. For the hackage server I'm using a combination of in-memory indexes and "blob" storage for large objects like tarballs. I'm also designing some compact data structures for other indexes (eg tarball contents). So far so good.
That said, I don't trust the state migration for upgrades etc. That's not because I've found that it doesn't work in practice but because as one of the authors of the binary package I'm worried by the fragility of Binary class instances. For the hackage server I'm going to implement a dump/restore in a separate non-binary format and use that for backups and as an escape mechanism if upgrades do not go well.
- documentation and examples at the level of python frameworks such as django
- rich support for typical web 2.0 app needs - styling, ajax, forms, authentication etc.
- full support for non-ascii content everywhere
All, as I have been learning how to be a dad, I have also had some
time to reflect on the goals I initially had for Happstack. I have
also been scanning the various topics that have been appearing on the
list. One thing that has become apparent is that happs has grown into
a framework that is being used for very many purposes -- and that
people have very different needs.
That said, I would like to focus on narrowing the scope of the project
a bit more and drive towards a common goal.
What is Happstack at this point in the road? Here are some of the
parts of the puzzle:
- a fairly mature http application server
- a fairly immature frontend http server (ipv6 and file serving -- to
name a couple of the areas of weakness)
- a fairly immature prevayler style persistence layer (lack of tools
and learning curve are a couple of issues here)
- a mixed bag of mature and immature utility functions of which some
are slowly decaying (in terms of maintenance)
Each of these four aspects could easily be a full-time job for one developer
Some open questions to the community:
1. How valuable do you find each of these pieces to be in your work
(whether it be personal or professional)?
2. What do you see as the main weakness of the current implementation
and/or community?
3. Which items could be potentially taken away to ease the overall
code footprint with minimal impact and/or which items really belong in
a separate project alltogether (state anyone?).
Regards,
Matthew Elder
--
Sent from my mobile device
Need somewhere to put your code? http://patch-tag.com
Want to build a webapp? http://happstack.com
> - frontend http server - useful. Btw, if you think it's not that good,
> why not use mohws (http://hackage.haskell.org/package/mohws)? Or
> maybe merge happstack http server with mohws?
One of my goals for Hac Phi is to allow for alternate HTTP backends for
Happstack. Matt Elder mentioned wanting to try Hyena as a backend also,
and personally out of all of the alternatives I find the iteratee-based
approach the most promising. I'll mohws to my "to-read" list (although
it doesn't seem to have too much in the way of source-level
documentation).
There isn't too much coding involved in writing a shim layer between
happstack ServerParts and other Haskell web libraries, it should mostly
be a matter of translating between Requests and Responses. Then we can
line up the servers and race them :)
> Happstack would be very useful for me if it had end-to-end type
> safety. Combined with expressive type system that would be a killer
> feature. That's, also, one of the features HAppS promised.
Could you please elaborate a little bit on what you mean by "end-to-end
type safety" or "expressive type system"? What in particular is missing
that you would like to see?
> Maybe, I'll be at Hac Phi too.
That's great, it looks like there will be enough people attending who
are interested in happstack for us to be able to make some real progress
towards some of these goals.
> I picked mohws just because it's the one of oldest haskell http
> servers: so it's likely to be stable. I haven't looked at Hyena, but
> it has even less docs than mohws :)
Also its interface is in flux, Johan seems to want to rewrite it to use
the left-fold definition from the iteratee library (a good idea in my
opinion).
There's also the standard "HTTP" library, which has some request-parsing
stuff in it, we should consider trying it out also. Happstack should
probably support FastCGI (if it doesn't already?) as well.
>> There isn't too much coding involved in writing a shim layer between
>> happstack ServerParts and other Haskell web libraries, it should mostly
>> be a matter of translating between Requests and Responses. Then we can
>> line up the servers and race them :)
>
> Good idea. What about that new Hack library in Hackage?
> http://hackage.haskell.org/package/hack
> Would it do the trick?
Sorry for not being precise -- I meant it should be easy to write
shim*s* (plural) between Happstack and other Haskell web libraries. If
you take a look at Happstack.Server.HTTP.Types, it already looks awfully
similar to that "Hack" package.
I envisioned that part of Happstack serving a similar role as the "Rack"
interface, i.e. a common-sense interface between web server libraries
and application server code.
>> Could you please elaborate a little bit on what you mean by "end-to-end
>> type safety" or "expressive type system"? What in particular is missing
>> that you would like to see?
>
> Here's what I meant: I should be able to program with native haskell
> ADT's and have them be safely converted to/from wire/storage formats
> when needed. I didn't mean this doesn't work at all (in fact it does
> work well with XML). But somehow it didn't work very well for me.
> Maybe having a high-level rails-like library gluing the parts together
> to make things like that dead simple would be nice -- but that
> wouldn't be possible until all of the components (especially,
> persistence) are mature. I think I wrote something along these lines a
> while ago.
I think we're in agreement that the core stuff should mature before we
really tackle that. I've (tediously, by now) already voiced my doubts
about "one ring to rule them all" data layers :)
> Happstack should probably support FastCGI (if it doesn't already?) as
> well.
Mea culpa, don't know why I didn't notice
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/happstack-fastcgi
before.
> If your app uses 50 mb in fcgi it will also use 50 mb as a backend
> http server as they are both daemonlike persistent processes; why are
> we so worried about supporting fcgi?
In principle I'm inclined to agree with you, on the other hand there's
little reason NOT to support it -- happstack-fastcgi is only ~220
LOC. FastCGI is supposed to be marginally more efficient (~5%?), and if
you use it e.g. lighttpd will spawn/kill your server instances for you
(also not such a big deal...)
Can we agree that (for example) something like happstack-hyena might get
implemented using the same basic strategy as happstack-fastcgi? We
should be able to knock three or four of those out during Hac Phi, no
sweat. Maybe the http server should be split out from the "rack"-like
middleware layer in happstack-server, as "just another backend"?
> On Jun 21, 2:25 am, Gregory Collins <g...@gregorycollins.net> wrote:
>
>> Can we agree that (for example) something like happstack-hyena might
>> get implemented using the same basic strategy as happstack-fastcgi?
>
> I would think, no. It is my impression that happstack-fastcgi is a
> glue layer that translates fastcgi requests into happstack-server
> Requests which are then handled by the normal happstack-server code as
> if it was a normal Request? On the other hand, Hyena is a complete
> replacement for happstack-server.
OK, let's go over this. Happstack-server contains:
1. datatype definitions for Request/Response types:
http://happstack.com/docs/0.2/happstack-server/0.2/Happstack-Server-HTTP-Types.html
2. a monad transformer stack for defining and building web
applications, having neat features like filtering/monoid
instances/short-circuiting/etc. (i.e. ServerPartT):
http://happstack.com/docs/0.2/happstack-server/0.2/Happstack-Server-SimpleHTTP.html
This layer depends on the types from #1 above.
3. code which listens on a socket, speaks the HTTP protocol, parses
Requests, passes Requests to a function of type (Request -> IO
Response), and sends the Response back out to the socket (i.e. the
actual "web server" part):
http://happstack.com/docs/0.2/happstack-server/0.2/Happstack-Server-HTTP-LowLevel.html
Application code is written to the interfaces of #1 and #2, the use of
#3 is not mandatory -- indeed happstack-fastcgi works by replacing
happstack's HTTP protocol stuff with a shim that translates types from
the fastcgi library (which defines its own Request/Response types) to
happstack's types (#1 above), then runs the monad transformer from #2 by
calling runServerPartT/runWebT. Happstack's HTTP serving stuff is
bypassed altogether (out of all of those pieces, it's the most suspect).
I'm proposing that a similar shim layer could be written for hyena.
> Hyena defines an generic "Web Application Interface" which could be
> used by any web backend:
So does happstack :)
> In theory, if happstack-server, hyena, and happstack-fastcgi all used
> this interface, then you could use happstack-server or hyena with
> happstack-fastcgi, and happstack-fastcgi would not have to have any
> code that was specific to either one.
I think you're confused about happstack-fastcgi, it's just a thin
adapter to the pre-existing fastcgi library from hackage (which speaks
the fastcgi protocol). You could write a similar shim for apps written
to run on hyena (because hyena defines its own version of #1), maybe
that's what you meant?
I agree that if all of the libraries wrote to the same interface, then
there would be no need for any adapter layers -- this is what the "Rack"
interface does for Ruby. The haskell "Hack" library mentioned yesterday,
a Rack clone, has a similar intention.
> Though, I expect that converting happstack-server to use Network.Wai
> would not be backwards compatible...
Yes, it would break all of the apps, because those are written against
the app-level interface.
> And I also hacked up an incomplete version of SimpleHTTP that is based
> on Hyena:
>
> http://src.seereason.com/examples/happstack-hyena-tutorial/simpleHyena.hs
This is exactly the kind of shim layer I was proposing! Are we on the
same page yet? :)
G.
--
Gregory Collins <gr...@gregorycollins.net>
> In terms of the data types for Request/Response, I think the reason to
> prefer hyena's version is that you can implement lazy I/O on top of
> left-fold enumeration, but not the other way around. However, I am not
> really sure how this would play out in practice.
One of the things I wanted to do for Hac Phi was to spend some time
reworking the ServerPartT stuff:
* it has an awkward name
* the towering ServerPartT/WebT/FilterT/MaybeT/ErrorT stack is
unnecessarily complicated, which scares away beginners
* ServerPartT leaks its internals out all over the place
While we're looking at that, we could spend some time thinking about the
response type also. We've already discussed extending it to support
sendfile(), we could put in iteratee support there also.
The simplest way discussed so far is to add more constructors to the
RqBody type:
data RqBody = Body ByteString
| Stream (StreamG ByteString Word8)
| SendFile FilePath
> And, if you are thinking of taking the stuff in SimpleHTTP
> (ServerPartT, dir, path, etc), moving it out of happstack-server into
> its own package, and generalizing it so that it can work with
> happstack-server, hyena, etc, then I am totally in favor of that.
That would indeed be what I'd propose.
> I think the tricky part of doing that right now is that ServerPartT,
> dir, path, etc, are pretty tightly integrated with the specific
> Request/Response types in happstack-server. So, you either need to add
> a type class that abstracts out the type, or get happstack-server and
> hyena to use the same type of the Response/Result ? Or, I guess, write
> a glue layer than converts between hyena's types and the Response/
> Request type (which is what the current happstack-fastcgi does?)
To me, ServerPart needs to depend on a particular set of
Request/Response types, so I'd argue for going by the latter route.
I want to add that I am currently working on the prototype of a small shim library which exposes a sendfile interface portably. I have windows natively supported already; I will release version 0.1 once I add Linux native support. Another nice feature of this lib is that if no native implementation is available, it seamlessly falls back to a portable haskell implementation. This hopefully can be worked into http engines such as Hyena and "happs classic".
My only problem with this is that bytestring really has nothing to do
with sendfile, and more to do with network. If anything I would merge
it into network. For now I am releasing on hackage to stabilize it,
though.
The simplest way discussed so far is to add more constructors to the
RqBody type:
data RqBody = Body ByteString
| Stream (StreamG ByteString Word8)
| SendFile FilePath
> The simplest way discussed so far is to add more constructors to the
> RqBody type:
>
> data RqBody = Body ByteString
> | Stream (StreamG ByteString Word8)
> | SendFile FilePath
>
> Gregory, didn't you mean Response?
...yeah, I guess I did. Sorry, I mucked up Request (which has that
RqBody type) and Response (which just uses a plain bytestring now.)
Note that between Response and the new SendFile constructor you're
planning on introducing, the only difference is the body type; maybe we
should think about moving SendFile / left-fold (if we do that) down into
the body type?
Either way would be fine, of course, it's an aesthetic decision.
> That would work, yeah, let me sleep on that. (Just changed violet's
> diapers)
It'd be a backwards-incompatible change, so let's save it for the
upcoming ServerPart refactoring.
Jinjing Wang has already had some success getting a happstack app
(gitit) running through his 'hack' (a rack-like middleware layer):
http://groups.google.com/group/gitit-discuss/browse_thread/thread/829595e063caf587
He was even able to run gitit on hyena this way, though he needs some
help with the hyena interface.
John
--
Getting in late on this discussion as I was busy
packing/moving/unpacking, but I strongly second this sentiment.
Also, I saw that there was a bit of discussion about future work on
Happstack-State, multimaster, & sharding. To be honest, my main
interest in the Happstack project is working on the persistence model
& backend so I'm more than willing to take lead on any effort to
rewrite the macid implementation if no one is chomping at the bit.
Sorry, I made an awful word choice. I meant 'revise', as in stream
line, polish, & finish. Regardless of my linguistic handicap, I think
we're on the same page.