0

I have a Grails 3 web application. After a client sends a request to my application, a long-running process starts, the process completion can take a few seconds or a few hours. I don't want to block the client to wait for the response. Therefore, I start a new thread for the process, but when the process execution completed, I can not update the client to know that the process has completed. After some search, I came across to WebSockets which might be a solution or maybe there are better solutions exists.

I would like to know what are possible good solutions (grails plugins) for this problem.

Thank you.

Memin
  • 3,788
  • 30
  • 31

2 Answers2

1

...the process completion can take a few seconds or a few hours.

Sending a response to a browser hours after the request was initiated is prone to a number of challenges but assuming you have all of that worked out, instead of starting a thread yourself you should use the async support in the framework. Lots of information available at https://async.grails.org/latest/guide/index.html. The details will depend on specifically what your long running process is doing, but likely you will be interested in the Server Sent Events section.

I hope that helps.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • Actually the async (thread initiation) is done. Only thing I need to send back to the client is the information that the process successfully completed. As I am very new to grails framework, I don't know what would be best to use. – Memin Mar 10 '18 at 23:31
0

You can use Async features of Grails which is building on top of RxJava,GPars and Reactor

Example:

import grails.async.Promise
import static grails.async.Promises.*

def longRunningTask() {
        Promise p = task {
            // Long running task
            return "Long running task completed"
        }
        p.onError { Throwable err ->
            println "An error occured ${err.message}"
        }
        p.onComplete { result ->
            //notify/update the client to know that the process has completed
            println "Promise returned: $result"
        }
    }

Also you can refer Event Publishing

Rahul Mahadik
  • 11,668
  • 6
  • 41
  • 54
  • I have spent a few hours to try your code to see if it can send response back to client after long running task, but no chance. It seems the Promise only fork the work. The challance I face is as follows. User tiggers the task, and the task starts as a new thread, so we return the response to user so they know task STARTED. But once task completed at background, I cannot send another information to client to know the task now COMPLETED. It seems to me it is not possible with Promise with its current format. Thanks for your reply. – Memin Mar 12 '18 at 13:28