clojure-liberator/liberator — pull request #113 by dthume (2014-03-23 07:18:35+00:00)
Title: Core.async Support

As per #91 I've added core.async support to liberator. Simply return true from the new ````:async?```` decision, then return a core.async channel from any subsequently resource function in order to enable non-blocking mode. I'll raise a separate pull request for accompanying docs.

Please note the following:

1) The ````:async?```` decision result is not actually used internally by liberator at the moment, but I've keep it as part of the API to allow us to potentially experiment with different approaches later.

2) I've tried a number of different approaches to implementing this - this pull request contains the least disruptive (to the code base) of those approaches - the new support is backwards compatible with existing liberator users, and core.async support is entirely optional (albeit it _is_ required on the classpath), at the price of one somewhat ugly macro. Internally the majority of the flow is unchanged, and although some of the larger functions have been split up in order to keep "pure" logic out of the ````go```` blocks, the implementation of those functions has not changed.

Other approaches that I tried yielded somewhat better performance for traditional (sync) requests (almost as fast as liberator master is at the moment), but the resulting code complexity / ugliness wasn't worth it IMO, and the performance of the current code is acceptable (again IMO) given that it is, in general, completely dominated by user code. That said I'm quite happy to use a more invasive approach if folks feel strongly about it. The perforate tests can be used to compare the two styles, and branches, assuming PR #112 is accepted.