Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for async #91

Closed
ansman opened this issue Nov 28, 2013 · 17 comments
Closed

Support for async #91

ansman opened this issue Nov 28, 2013 · 17 comments

Comments

@ansman
Copy link
Contributor

ansman commented Nov 28, 2013

It would be nice if liberator would support async endpoints.

One way to do it would be to use core.async. If a handler/action/decision returns a core.async channel the caller should also return a channel.

If there is interest for it I'd be happy to take a shot at an implementation.

@ordnungswidrig
Copy link
Member

How would the integration work? I did not find anything about the ring spec supporing core.async or any other mechanism for server push.

@ansman
Copy link
Contributor Author

ansman commented Nov 29, 2013

Actually, I'm using http-kit which supports async requests.

@jeluard
Copy link
Contributor

jeluard commented Nov 29, 2013

Do you have some specific idea in mind?

http-kit async support is mostly useful for websockets and long-polling/SSE but that doesn't really fit liberator REST-like model.
What would that add compared to just handling those outside liberator?

@ansman
Copy link
Contributor Author

ansman commented Nov 29, 2013

The thing is that I will be talking to Facebook in my app which takes quite a long time so I don't want to lock a thread while doing this.
I will be using WS but most of my app will be async REST endpoints.

If I don't use liberator I will have to do content negotiation and things like that on my own, something I would like to avoid.

I would say that async is a crucial part of any high performance web server.

@jeluard
Copy link
Contributor

jeluard commented Nov 29, 2013

Ok I was discussing something different then. Sounds similar to pedestal async processing concept. Also see #56.

@ansman
Copy link
Contributor Author

ansman commented Nov 29, 2013

Yeah, it sounds similar.

Not sure what pros or cons the pedestal solution has but it seems a bit messy to me.

I guess the pro with core.async is the nice syntax but a downside is it isn't supported by ring.

@jeluard
Copy link
Contributor

jeluard commented Nov 29, 2013

Looks messy to me too. Relying on core.async seems cleaner and easy to plug with http-kit (if it does not move to core.async itself?).
Look forward to see some more details on this :)

@ansman
Copy link
Contributor Author

ansman commented Nov 30, 2013

I'll get some code together and you can see what you think.

@ordnungswidrig
Copy link
Member

Having blocking requests just because you have a long backend request seems unnecessary to me. I suggest to response with 202 Accepted or 303 See other, where either response would redirect to a resource representing the actual result of the long running request.

@ordnungswidrig
Copy link
Member

In case of a streaming response, e.g. web chat, then some way of providing an async response could be fine. However, this is something that must be supported by ring the adapter. Ring allows the handler to return an InputStream; I don't know if this is a viable option to stream a response to the client.

@ordnungswidrig
Copy link
Member

FYI there is http://ring-clojure.github.io/ring/ring.util.io.html#var-piped-input-stream which you can return from a handler.

@jconti
Copy link

jconti commented Jun 19, 2014

With reference to returning a 202 or 303 for a long running task, long polling is useful then in the case where a client wants to then block on the resource that represents the long running task. Automated clients can decide if they want to follow to the new link and long poll (like a browser), or just poll the endpoint with a timeout asynchronously. I think this is useful, I've been using something similar for pub/sub over HTTP that has worked out quite nicely. Such a solution is easily debugged with a browser, and flexible for clients (they can choose async or sync).

@xfeep
Copy link

xfeep commented Aug 9, 2014

If we let liberator run on nginx-clojure which supports ring handler and after we enable coroutine based socket from nginx-clojure , the socket blocking won't lock a thread anymore. Our old code which based on synchronous blocking Java Socket API need not be changed and the executions of them will become non-blocking.

@cch1
Copy link
Contributor

cch1 commented May 5, 2017

After much dwell time, ring-clojure has released version 1.6 which supports async processing. The model that it supports is mechanically convertible to aleph and http-kit. It would seem that the ring model (an arity-three handler function) would work nicely with liberator's content negotiation and validation functionality.

@ordnungswidrig
Copy link
Member

Core.async is independent of support of Ring's new async response processing. I think the latter would be a good feature and deserves discussion. Let's close this issue and have a separate one for Ring's async support.

@ordnungswidrig
Copy link
Member

See #280.

@cch1
Copy link
Contributor

cch1 commented May 7, 2017

Sounds like a good idea. I did not realize this issue was just for core.async, but it makes sense to separate the issues as support for one does not imply support for the other.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants