[ANN] Async Ring 0.1.0

1,873 views
Skip to first unread message

David Greenberg

unread,
Sep 9, 2014, 11:25:04 AM9/9/14
to clo...@googlegroups.com, ring-c...@googlegroups.com
Announcing the release of Async Ring! Ring is a great foundation for building HTTP servers in Clojure. However, Ring fails to solve many problems that high-performance and transactional HTTP servers must solve:

  • What does the server do when it can't handle the request rate?
  • How can the server dedicate more or fewer resources to different requests?
  • How can long-running HTTP requests be easily developed, without blocking threads?

Async Ring attempts to solve these problems by introducing a core.async based API that is backwards compatible with Ring and popular Ring servers, so that you don't need to rewrite your app to take advantage of these techniques.


Async Ring comes with many features:
  • Ports of most ring middleware (just ask me and I'll port your favorites!)
  • Beauty, a compojure & clout compatible concurrent quality-of-server router
  • Integration with Jetty and Http-Kit, more coming
  • Documentation and Examples


Feedback and pull requests welcome!

Timothy Baldridge

unread,
Sep 9, 2014, 11:35:19 AM9/9/14
to clo...@googlegroups.com
How does this compare/contrast with Pedestal. Seems like there might be some overlap here?

Timothy

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
“One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.”
(Robert Firth)

László Török

unread,
Sep 9, 2014, 12:43:45 PM9/9/14
to clo...@googlegroups.com
There seems to be a https://github.com/dgrnbrg/async-ring#comparison-with-pedestal section in the README
László Török
Checkout Lollyrewards.com - Giving credit, getting credit. 
Follow us on Twitter @lollyrewards
Stay up to date on the latest offers by liking our Facebook page.

James Reeves

unread,
Sep 9, 2014, 12:50:11 PM9/9/14
to clo...@googlegroups.com, ring-c...@googlegroups.com
Hi David,

This looks very interesting, however I'd like to request that you change the name to make it clear this project isn't an official part of Ring. Usually I don't mind if a library uses "Ring" in its name, but in this case it seems like there could be a future source of confusion if Ring itself adopts an asynchronous approach.

- James


--

dgrnbrg

unread,
Sep 9, 2014, 3:22:58 PM9/9/14
to clo...@googlegroups.com, ring-c...@googlegroups.com, ja...@booleanknot.com
Async Ring has been renamed to Spiral, a Ring that doesn't block, to avoid future confusion.

David Greenberg

unread,
Sep 9, 2014, 3:23:03 PM9/9/14
to ring-c...@googlegroups.com, clo...@googlegroups.com, ja...@booleanknot.com
Async Ring has been renamed to Spiral, a Ring that doesn't block, to avoid future confusion.

bob

unread,
Sep 10, 2014, 12:57:07 AM9/10/14
to clo...@googlegroups.com, ring-c...@googlegroups.com
Great, I just wonder how you evaluate the performance, how many concurrences? how many requests?

Paul deGrandis

unread,
Sep 10, 2014, 6:29:11 AM9/10/14
to clo...@googlegroups.com, ring-c...@googlegroups.com, ja...@booleanknot.com
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

dgrnbrg

unread,
Sep 10, 2014, 8:36:07 PM9/10/14
to clo...@googlegroups.com, ring-c...@googlegroups.com, ja...@booleanknot.com
Hi Paul,
Thanks for your feedback! I updated the comparison with pedestal when discussing the async queues to address this point.

I am also really excited about Jet--I think that it would be a great combination with Spiral!

One key difference in Spiral from Jet and Pedestal is that not only can you use core.async to make an async handler, but you can also make async middleware using core.async as well.
Reply all
Reply to author
Forward
0 new messages