|
I'm trying to figure out how to update a progress bar, based on the progress of a background task. The task might take a long time, and I want the use to be able check the status at any time, even across sessions. So I'm saving the status in the database. Just working on example application right now. And from what I've learned so far, there's doesn't seem to be a good way to the background task itself update the client, since it's not part of the user's session. So right now, I'm trying to poll the database. (That's actually not really working, but my previous question was about that issue.) But I'm wondering if there's a better way to do that.
I started looking at JMS a bit, but I'd rather not have to install a separate server, just for this. And that's how I got to the polling solution to begin with. But if JMS is really a better way, I'm open it.
Thanks for the help! def backgroundAction = { println "backgroundAction" def theEvent = Event.get(params.id)
def duration = theEvent?.duration ?: 10 def name = theEvent?.name ?: "none" def percentComplete = theEvent?.percentComplete ?: 0
def lastPct = -1 runAsync { toEvent(name,duration,percentComplete,false) } while(percentComplete < 100) {
println "percentComplete:${percentComplete}" if (percentComplete != lastPct ) { progressService.setProgressBarValue(name, percentComplete)
lastPct = percentComplete } def newEvent = Event.get(params.id) percentComplete = theEvent.percentComplete
} render "the progress is done" } www.maf.org/rhoads www.ontherhoads.org |
|
+1 to jms vs a db, you can use an embedded broker. Use a topic to send updates. ActiveMQ also has an xmpp channel. On Aug 6, 2011 1:33 PM, "Brad Rhoads" <[hidden email]> wrote:
> I'm trying to figure out how to update a progress bar, based on the progress > of a background task. The task might take a long time, and I want the use to > be able check the status at any time, even across sessions. So I'm saving > the status in the database. Just working on example application right now. > And from what I've learned so far, there's doesn't seem to be a good way to > the background task itself update the client, since it's not part of the > user's session. So right now, I'm trying to poll the database. (That's > actually not really working, but my previous question was about that issue.) > But I'm wondering if there's a better way to do that. > > I started looking at JMS a bit, but I'd rather not have to install > a separate server, just for this. And that's how I got to the polling > solution to begin with. But if JMS is really a better way, I'm open it. > > Thanks for the help! > > def backgroundAction = { > > println "backgroundAction" > > def theEvent = Event.get(params.id) > > def duration = theEvent?.duration ?: 10 > def name = theEvent?.name ?: "none" > def percentComplete = theEvent?.percentComplete ?: 0 > def lastPct = -1 > > runAsync { > toEvent(name,duration,percentComplete,false) > } > > while(percentComplete < 100) { > println "percentComplete:${percentComplete}" > if (percentComplete != lastPct ) { > progressService.setProgressBarValue(name, percentComplete) > lastPct = percentComplete > } > def newEvent = Event.get(params.id) > percentComplete = theEvent.percentComplete > } > > render "the progress is done" > } > > > --------------------------- > www.maf.org/rhoads > www.ontherhoads.org |
|
In reply to this post by bdrhoa
I think you may be having a caching/timing issue.
did you try refresh after your gets? def theEvent = Event.get(params.id) theEvent.refresh() or try using a findById instead of a get as it won't be cached by default. On Aug 6, 2011, at 3:33 PM, Brad Rhoads wrote:
|
|
Thanks, that's what I needed to get my polling solution to work...
--------------------------- www.maf.org/rhoads www.ontherhoads.org On Sat, Aug 6, 2011 at 8:16 PM, basejump (Josh) <[hidden email]> wrote:
|
|
In reply to this post by basejump (Josh)
I was pleasantly surprised how easy it was to get started with ActiveMQ. It was quite easy to setup sending and receiving messages in general. But when the service gets the message, I can't get the user's session to actually update the progress bar. So how can I get the message in the controller?
Or do I have to use ActiveMQ AJAX? The JProgress plugin is working well as long as I have a session, but maybe I need to update it to use JMS/ActiveMQ? Other options? Details below.
Thanks! -Brad
The browser posts to this action, which kicks off a background process: def backgroundAction = { println "backgroundAction"
def theEvent = Event.get(params.id) def duration = theEvent?.duration ?: 10 def name = theEvent?.name ?: "none"
def percentComplete = theEvent?.percentComplete ?: 0 def lastPct = -1 runAsync { toEvent(name,duration,percentComplete,false)
} } Then the background process sends a message when an update is complete: def toEvent(name,duration,startAt,updateBar) {
println "duration:${duration}" println "name:${name}" println "startat:${startAt}" for (int i = startAt; i <= 100; i++) {
println "i:${i}" def theEvent = Event.findByName(name) theEvent.percentComplete = i theEvent.save(flush:true)
println "theEvent.percentComplete:${theEvent.percentComplete}" if(updateBar){ progressService.setProgressBarValue(name, i)
} else { sendJMSMessage("queue.notification", "${i}") } //let's waste some time
for (int a = 0; a < duration; a++) { for (int b = 0; b < 1000; b++) { } } }
} Then I want the OnNotificationService to update the progress bar, but it can't get the session: 2011-08-08 11:52:14,123 [onNotificationJmsListenerContainer-1] ERROR OnNotification.onMessage - Exception raised in message listener
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'onMessage' threw exception; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
class OnNotificationService {
def progressService boolean transactional = false static exposes = ['jms'] static destination = "queue.notification"
def onMessage(name){ println "GOT MESSAGE: ${name}" // def theEvent = Event.findByName(name) def percentComplete = name.toLong()// theEvent?.percentComplete ?: 0
//println "name:${name}" println "percentComplete:${percentComplete}" progressService.setProgressBarValue("One", percentComplete)
} } --------------------------- www.maf.org/rhoads www.ontherhoads.org On Sat, Aug 6, 2011 at 8:16 PM, basejump (Josh) <[hidden email]> wrote:
|
|
"Or do I have to use ActiveMQ AJAX?"
Yes, checkout the REST ActiveMQ Connector too (use CURL before even trying with your app).
"The JProgress plugin is working well as long as I have a session, but maybe I need to update it to use JMS/ActiveMQ?"
If you decide to go all the way with the JProgress plugin let me know. I think it will be best if we can offer a JProgress-JmsConnector component that depends on both the JProgress and the JMS plugins. I will suggest you try to avoid storing state in the session for this matter and hope you don't need to capture absolutely all the sampling points of the Job's progress. Cheers. Bernardo.
On Mon, Aug 8, 2011 at 11:06 AM, Brad Rhoads <[hidden email]> wrote: I was pleasantly surprised how easy it was to get started with ActiveMQ. It was quite easy to setup sending and receiving messages in general. But when the service gets the message, I can't get the user's session to actually update the progress bar. So how can I get the message in the controller? |
|
I'm trying to give this a go. I downloaded the ActiveMQ binaries and got the demo to run fine. But I'm stuck getting anything to work in a Grails app.
I added activemq-web-5.5.0.jar to my lib. But I don't know how to set the URI to point to it correctly. Do I need to do something the URL Mapping? Or?
<script type="text/javascript"> var amq = org.activemq.Amq; amq.init({ uri: '../amq', logging: true, timeout: 45 }); //WHAT SHOULD THE URI BE?
var testHandler = function(message) { document.getElementById("received").innerHTML = message.textContent; amq.removeListener("test", "queue://test");
} amq.addListener("test", "queue://test", testHandler); amq.sendMessage("queue://test", "passed"); </script> --------------------------- www.maf.org/rhoads www.ontherhoads.org On Mon, Aug 8, 2011 at 12:50 PM, Bernardo Gomez Palacio <[hidden email]> wrote:
|
| Powered by Nabble | Edit this page |
