Reputation: 410
I have a view that has a link using the g:link
GSP tag with action that runs and updates on a significant number of rows, so it takes some time. In the meantime, the browser is in limbo and times out after 30 sec (which is the timeout on the servlet container).
Problem:
Question:
How can I trigger the controller action and reload the page to the same view? Or is there a better way to handle this like triggering the action async?
I tried to reload the page using js, but it does not seem to reload the page. I have read about implementing a message queue, but it seems like a lot of work for a simple issue. Any ideas will be good. Thank you in advance.
View:
<li>
<a class=""
href="${g.createLink(controller: "hello", action: "dbAction")}">Run Update on DB
</a>
</li>
Controller Action:
def dbAction() {
some code...
myservice.dbAction();
redirect(action: 'index')progress"
}
}
My Service dbAction:
def dbAction() {
Sql sql = getSql()
sql.executeUpdate('''
update mytable
set
mydata = calculate_data,
updated_by = 'dbAction',
updated_at = now()
where
id in (1,2,3)
}
Upvotes: 1
Views: 119
Reputation: 190
I have exactly your problem. The query takes so long to run, the controller cannot respond back to the browser. So, the browser times out.
I tried 3 different ways to fix this.
The easy way out: I am using Tomcat. So, I set the connection timeout value longer. The connectionTimeout variable is in the server.xml file.
The lazy way out: I don't know if Grails has any sort of Message Queue function or not. So, I rolled my own. When I click the submit button to run a very long update query, the action will INSERT INTO a sort of update command in a database table along with the state. I then use Quartz to schedule maybe every 10 seconds to read this table to check the state. If the state is NEW, I change the state to "IN PROGRESS". And then I let the trigger to run the update query in the background. After it finish, I change the state to FINISH.
So, the action is just adding a row to the database and then respond back the view that says something like... You have issued the request. The system will process your request in a few moment.
The hard way out: I went over all my SQL and functions in the actions to calculate the time it will take the SQL and codes to finish the query. I then rearrange/rewrite the functions and procedures. I am not good enough for this. If I can get to O(n), that will be enough for me.
Upvotes: 1