Blocking on a Promise

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Blocking on a Promise

Rob Elliot
We're using the ClientSideSessionsModule for our SessionStorage implementation. Consequently we don't get any benefit from the change of SessionStorage to a Promise based API. I'm trying (and currently failing) to put a synchronous wrapper around it to save us the hassle of handling callbacks higher up the stack, but I can't work out how to block and synchronously retrieve the result of a promise; the equivalent of calling Future.get() in Java land. Is this even possible?

Thanks for any pointers,
Rob
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

danhyun
Hi Rob,

The motivation for wrapping Session interactions in Promises is to provide a consistent API regardless of the backing implementation. It's more the rule than the exception that backing session stores would be I/O heavy.

I don't believe it's possible to block on a value unless you're in a `ExecControl.blocking` or `Promise.blockingMap` call.

If you know you won't be switching the client backed session impl or you will only store everything as Strings, you could do something like this:
https://gist.github.com/danhyun/bfeb82ef96674d8d90a3

Another advantage to utilizing Ratpack's Promise API is that you can keep the Session stuff functional.
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

danhyun
I've forgotten that Ratpack can render promises!

This might help align the code to better fit your need.

I've updated my gist to show an example of rendering with promises:

https://gist.github.com/danhyun/bfeb82ef96674d8d90a3#file-example2-java
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

Rob Elliot
I'll take that as a "no" then. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

danhyun
Ratpack is a sharp departure from the traditional Servlet container based frameworks in that it's asynchronous, non-blocking, and reactive from the ground up. This means the entire framework is designed to facilitate a functional reactive approach to handling web requests. This makes it a lot easier to compose various components provided by Ratpack and Ratpack modules. Granted it takes a while to switch to this way of thinking from traditional blocking Servlet approach but when the lightbulb turns on it's very rewarding.

Here' a nice blog entry on the reactive approach to web applications http://ldaley.com/post/99527932537/executional-flexibility-through-reactive
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

danveloper
Administrator
In reply to this post by Rob Elliot
If you're dead-set on blocking, then you can do it with Ratpack's RxJava integration. Convert the Promise to an Observable and use a BlockingObservable to synchronously get your data out.

That said, I'll echo everything Danny has said. One of the ways that Ratpack achieves throughput of over a half million req/s is through an efficient resource footprint, supported by NIO and a small thread pool. If you block in a request taking thread, then it will not be available to satisfy subsequent requests, meaning that your throughput will drastically suffer.
Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

Luke Daley
Administrator

You can block on a promise using Promise.block(), but you can’t do this on a compute thread.

Reply | Threaded
Open this post in threaded view
|

Re: Blocking on a Promise

danhyun
We've added some convenience methods available in the latest snapshot which allows you to interact with SessionData from the Session.

http://ratpack.io/manual/snapshot/api/ratpack/session/Session.html

Old:

ctx.render(ctx.get(Session.class)
    .getData()
    .map(sessionData -> {
        SessionKey key = SessionKey.of(keyName, String.class);
        return sessionData.get(key).orElse(null);
}));
New:
ctx.render(ctx.get(Session.class)
    .get(SessionKey.of(keyName, String.class))
    .map(value -> value.orElse("null")));