Hi David, It's excellent to see this tools and others like it (eg: Max Penet's Jet - https://github.com/mpenet/jet)! The more ideas we get in this area, the better all the tooling will become. There are a few things I'd like to clear about the notion of asynchronous processing in general and the comparison to Pedestal specifically. I think in discussing the details, everyone will come out ahead.
1. The interceptor queue is merely the current path. In your comparison, you state that Pedestal forces Interceptors to be placed in a queue for execution. This isn't entirely accurate. You can arbitrarily specify the order of interceptors (imagine a graph of connected interceptors). The interceptor queue is merely the current path of interceptors executing (or scheduled to execute). Any interceptor can dynamically add more interceptors to that path during execution. The "interceptor" is the core abstraction from which all things are built in Pedestal - it's the only abstraction. I have written a predicate dispatch Interceptor that allows open/extensible rules to route requests - with the interceptor you can create a Liberator-style system, QoS-style routing, or anything of similar nature. I also have written a cond-interceptor, that does a one-off conditional dispatch. Both will probably land in Pedestal's base interceptors at some point. 2. One notion of concurrency in Pedestal is managed with core.async In your comparison, you state the concurrency mechanism is pure functions. This is also not accurate. The concurrency mechanism to signal to the container you're going async, is to have an interceptor return a core.async channel (we'll call this the "context channel"). In the application code, you continue forward using core.async. Once you want the web-server to resume processing your request, you place a context (a map) on the context channel (sometimes others refer to the context channel as the "resume channel"). I think what you're getting at is there's a notion of interceptors for entering, leaving, and handling errors - which I'll address in the next item. 3. There are two notions of async behavior - Pedestal delivers both. One notion of async behavior was discussed above - your application gives up the current/main execution thread, continues execution on another thread, and later gets resumed on one of the main execution threads. To truly do this in an asynchronous manner, one must separate the notion of request and response. This is why Pedestal uses a context, and why function composition and coupling request and response will limit (or prevent) async capabilities. To be async in this sense, you must never block the main execution thread at any point. Another notion of async behavior occurs when placing the actual response on the wire - most applications do so in a blocking manner using standard Java IO. Recently, Pedestal added the capability to do this in a non-blocking, asynchronous manner using NIO. That is, in Pedestal, if your response body is a ByteBuffer or a ReadableByteChannel, and you're running on a container that supports NIO (Jetty), it will use NIO through the entire container when handling the request. If a developer can't get manage to return a ByteBuffer or a ReadableByteChannel (or if the developer is on a container that doesn't support NIO), they can still return a core.async Channel and Pedestal will perform the standard IO response within a `go`. Using a core.async Channel has limits, and NIO should be preferred if available. 4. Routing and Extension Two pieces missing from the comparison were routing and general extension mechanisms. I won't dive too deep into the routing piece (it's data driven, can be programmatically consumed or generated, can be read off of the wire or out of a DB, etc), but I do want to touch upon the extension piece a bit. In Pedestal, all the major integration points are backed by protocols - including the async handling discussed above. This allows developers to shape and extend Pedestal to fit any operational need. Routing is also backed by protocols, which enables a developer to shape how routing endpoints should be interrupted. Pedestal's use of protocols throughout has proven extremely beneficial as I've tackled complex web systems. I hope this helps clarify some topics and I look forward to further discussion! Cheers, Paul -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.