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.

Reply via email to