I am new to writing WebServices and using a play framework. Currently I am trying to implement asynchronous call to WS using play framwork. My WS is likely to run for a long time and my client (browser) do not want to wait for that long.
I intend to run the WS in the background and when it completes the work, it will update the database. My client will keep on checking the database whenever user wants.
I have implemented below code in play :
public static Promise<Result> index(String name, String surname)
{
Promise<Integer> promiseOfInt = Promise.promise
(
new F.Function0<Integer>()
{
public Integer apply() throws InterruptedException
{
return intensiveComputation();
}
}
);
return promiseOfInt.map
(
new Function<Integer, Result>()
{
public Result apply(Integer i)
{
return ok("Got result: " + i);
}
}
);
}
public static Integer intensiveComputation () throws InterruptedException
{
Thread.sleep(7000);
return 7658;
}
I want my index() method to immediately intimate the client that it has successfully submitted the job and keep on checking the status periodically manually and that the intensive computation runs in the background. Currently my browser waits for 7 seconds and gets the string "Got result: 7658".
I have gone through http://www.playframework.com/documentation/2.2.x/JavaWS, but not fully understood how do I use Promise, Future to make client proceed and access the result later on. Request all to please help me understand this.
Right now you're doing this:
ok
result (only when it's finished)Maybe you should just create a new Promise
with your computation and without waiting for it to finish, immediately return ok
to a client?
This way you can do whatever you want with the result of the computation (write it to db etc.) and then your client can either check by himself the result of the operation or you can propagate the result to him using something like websocket
or server-sent event
.
Taking your example, you simply doesn't wait on the first promise and just return :
public static Result index(String name, String surname) {
// will be processed asynchronously
Promise<Integer> promiseOfInt = Promise.promise(new F.Function0<Integer>() {
public Integer apply() throws InterruptedException {
return intensiveComputation();
}
});
promiseOfInt.map(new Function<Integer, SomeReturnType>() {
public SomeReturnType apply(Integer i) {
// do smth like writing to db...
return new SomeReturnType("done!");
}
});
// returns immediately
return ok("Got result: " + i);
}