ejain
ejain

Reputation: 3614

How do I create and complete a play.libs.F.Promise?

I'd like to create a play.libs.F.Promise from a call to an async third-party service so I can chain the call and return a Promise<Result> instead of blocking inside the controller. Something like so:

final Promise<String> promise = new Promise();
service.execute(new Handler() {
  public void onSuccess(String result) {
    promise.complete(result);
  }
})
return promise;

Unfortunately, there does not appear to be a way to create an empty play.libs.F.Promise, and there is no method to complete a promise, either?

Upvotes: 3

Views: 5829

Answers (4)

Saeed Zarinfam
Saeed Zarinfam

Reputation: 10180

You can create F.Promise like this:

F.Promise<User> userPromise = F.Promise.promise(() -> getUserFromDb());

and use its value when it is ready:

userPromise.onRedeem(user -> showUserData(user));

Upvotes: 0

D. L.
D. L.

Reputation: 46

You have to use a F.RedeemablePromise.

RedeemablePromise<String> promise = RedeemablePromise.empty();

promise.map(string ->
  // This would apply once the redeemable promise succeed
  ok(string + " World!")
);

// In another thread, you now may complete the RedeemablePromise.
promise.success("Hello");

// OR you can fail the promise
promise.failure(new Exception("Problem"));

Upvotes: 1

Svetlana Simakova
Svetlana Simakova

Reputation: 1

You can return empty promise by doing the following:

return F.Promise.pure(null);

Upvotes: 0

Didac Montero
Didac Montero

Reputation: 2086

Assuming the current version of play and the play.libs.F.Promise, a promise can be created in two ways: 1) Using a scala Future and Callback or 2) using a play Function0 (replace A for any class):

import static akka.dispatch.Futures.future;
//Using 1)
Promise<A> promise=Promise.wrap(future(
    new Callable<A>() {
        public A call() {
        //Do whatever
        return new A();
  }
}, Akka.system().dispatcher()));

//Using 2) - This is described in the Play 2.2.1 Documentation
// http://www.playframework.com/documentation/2.2.1/JavaAsync 
Promise<A> promise2= Promise.promise(
  new Function0<A>() {
    public A apply() {
        //Do whatever
        return new A();
    }
  }
);

EDIT: When you can't modify the async block because it's provided by a third party you can use the approach of creating an empty Promise (scala promise, not play framework promise). Then you can use the Future containing the scala Promise to generate a play.libs.F.Promise as follows:

import akka.dispatch.Futures;

final scala.concurrent.Promise<String> promise = Futures.promise();
service.execute(new Handler() {
    public void onSuccess(String result) {
        promise.success(result);
    }
})
return Promise.wrap(promise.future());

Upvotes: 1

Related Questions