Question

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.

Was it helpful?

Solution

Right now you're doing this:

  1. Client makes a request and waits for the response
  2. You start a long-running computation
  3. You wait until the computation is finished
  4. You return the result of your computation to the client with 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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top