Re: struts & generating progress messages
Kitching Simon wrote: > Hi, > > I currently have a model-1 web application > ie in which the .jsp pages are responsible > for invoking the business logic. > > I am planning to move the webapp to struts, > for all the obvious and traditional reasons. > However, there is one nice feature of the > current code that I can't see how to perform > inside an MVC framework like struts: > > On submitting a particular form, there is a > sequence of 4 operations to perform, each of > which takes somewhere between 5 and 30 > seconds to perform. Currently, what is done is > to generate an almost complete HTML page, > and force it to be flushed to the browser; as > each long-duration step starts and completes, > a fragment of page containing CSS-positioned > html/ javascript is flushed to the browser. The > effect is very nice - a list of the steps appears > on the screen, an hourglass appears next to > each step as it starts, and a tick or error message > appears next to each one as it completes. > > Does anyone have any idea how to generate the > same sort of effect (essentially alternating between > business logic and presentation output) in struts? > As you've gathered, a model 2 approach is not amenable to using flushing to show progress. A strategy that might work better is something like this, in the initial Action that starts all of the work: * Fire off a background thread to do the long-duration work. * Give this thread access to the user's session, so it can update a status variable when it is done * Return a "work in progress .. click here to check for completion" page, which returns to the same action * When the action is entered, it will check to see that a background thread is currently running, so it will display another "work in progress" page, or the final results, depending on what's been done so far. * When the background thread completes its work, it updates the final status and exits. Variations on the theme: * The status variable need not be binary -- for a multiple stage background operation, it could be a state identifier, or a percentage completed, or something like that, so you can be more descriptive on the "in progress" page. * You might want to generate a meta refresh tag on the "in progress" page, so that the user doesn't have to remember to hit the link. > > Thanks in advance, > > Simon Craig
RE: struts & generating progress messages
> -Original Message- > From: Craig R. McClanahan [SMTP:[EMAIL PROTECTED]] > Sent: Friday, January 05, 2001 8:28 PM > To: [EMAIL PROTECTED] > Subject: Re: struts & generating progress messages > > Kitching Simon wrote: > > > Hi, > > > > I currently have a model-1 web application > > ie in which the .jsp pages are responsible > > for invoking the business logic. > > > > I am planning to move the webapp to struts, > > for all the obvious and traditional reasons. > > However, there is one nice feature of the > > current code that I can't see how to perform > > inside an MVC framework like struts: > > > > On submitting a particular form, there is a > > sequence of 4 operations to perform, each of > > which takes somewhere between 5 and 30 > > seconds to perform. Currently, what is done is > > to generate an almost complete HTML page, > > and force it to be flushed to the browser; as > > each long-duration step starts and completes, > > a fragment of page containing CSS-positioned > > html/ javascript is flushed to the browser. The > > effect is very nice - a list of the steps appears > > on the screen, an hourglass appears next to > > each step as it starts, and a tick or error message > > appears next to each one as it completes. > > > > Does anyone have any idea how to generate the > > same sort of effect (essentially alternating between > > business logic and presentation output) in struts? > > > > As you've gathered, a model 2 approach is not amenable to using flushing > to show > progress. A strategy that might work better is something like this, in > the > initial Action that starts all of the work: > > * Fire off a background thread to do the long-duration work. > * Give this thread access to the user's session, so it can > update a status variable when it is done > * Return a "work in progress .. click here to check for completion" > page, which returns to the same action > * When the action is entered, it will check to see that a > background thread is currently running, so it will display > another "work in progress" page, or the final results, depending > on what's been done so far. > * When the background thread completes its work, it updates > the final status and exits. > > Variations on the theme: > * The status variable need not be binary -- for a multiple > stage background operation, it could be a state identifier, > or a percentage completed, or something like that, so you > can be more descriptive on the "in progress" page. > * You might want to generate a meta refresh tag on the > "in progress" page, so that the user doesn't have to remember > to hit the link. > > > > > Thanks in advance, > > > > Simon > > Craig > [Kitching Simon] Thanks very much for your reply! I don't like the link or refresh idea much, but your suggestion of a "background thread" triggered another idea for me... How about the action starts a threaded business class, then forwards to the presentation page. This business class has methods waitForStep1(), waitForStep2(), etc, which when called do a wait() on a member variable. As the thread completes each step, it calls notify() on the corresponding member variable. The presentation page generates & flushes output, then calls waitForStep1(), thereby blocking. When the function returns, it outputs the results, and calls waitForStep2(), etc. In effect, we have an action "piping" results to a presentation page that is running in parallel with it. Do you think this will work? And do you think that this might be worth making part of the framework? It sounds quite tidy to me Thanks again, Simon
Re: struts & generating progress messages
Kitching Simon wrote: > Hi, > > I currently have a model-1 web application > ie in which the .jsp pages are responsible > for invoking the business logic. > > I am planning to move the webapp to struts, > for all the obvious and traditional reasons. > However, there is one nice feature of the > current code that I can't see how to perform > inside an MVC framework like struts: > > On submitting a particular form, there is a > sequence of 4 operations to perform, each of > which takes somewhere between 5 and 30 > seconds to perform. Currently, what is done is > to generate an almost complete HTML page, > and force it to be flushed to the browser; as > each long-duration step starts and completes, > a fragment of page containing CSS-positioned > html/ javascript is flushed to the browser. The > effect is very nice - a list of the steps appears > on the screen, an hourglass appears next to > each step as it starts, and a tick or error message > appears next to each one as it completes. > > Does anyone have any idea how to generate the > same sort of effect (essentially alternating between > business logic and presentation output) in struts? > > Thanks in advance, > > Simon How about creating a separate thread to perform the tasks, and forwarding immediately to the jsp page in your main thread. Create an object which can wait for the tasks to complete, and attach that object to the request before forwarding. As an example, create a TaskMonitor (sample code below; this code is untested, and I usually don't program threads so don't trust it to work without some scrutiny). Task thread. Create a thread to perform your tasks and give it a reference to this monitor. Each time a task is complete, call monitor.taskComplete(taskid). Main thread. Attach monitor to request. Forward to jsp. The jsp can call monitor.waitForTask(taskid) for each task in sequence. public class TaskMonitor { boolean[] taskComplete; public TaskMonitor(int taskCount) { taskComplete = new boolean[taskCount]; } public synchronized waitForTask(int taskid) { if (taskid < 0 || taskid >= taskComplete.length || taskComplete[taskid]) return; while(true) { try { wait(); } catch(InterruptedException ie) { } if (taskComplete[taskid]) return; } } public synchronized taskComplete(int taskid) { if (taskid > 0 && taskid < taskComplete.length) { taskComplete[taskid] = true; notifyAll(); } } }
RE: struts & generating progress messages
Thanks, Jim! A reply in about 5 minutes, complete with pseudo-code - I'm impressed :-) As you probably saw from my reply to Craig, a similar idea occurred to me - after the idea of creating a separate thread to perform business processing was suggested. I like your idea of a generic TaskMonitor "synchronizer" object that essentially mediates between the action and the presentation slightly better than my idea of building it into the class doing the actions too - the TaskMonitor could even be a standard utility class, with it's array of Booleans (if I understand your code right). All the action & page need to agree on is a set of constants (probably best defined in an interface) to use as the task ids... Anyway, plenty to ponder. Cheers & thanks again, Simon > -Original Message- > From: Jim Newsham [SMTP:[EMAIL PROTECTED]] > Sent: Friday, January 05, 2001 8:36 PM > To: [EMAIL PROTECTED] > Subject: Re: struts & generating progress messages > > Kitching Simon wrote: > > > Hi, > > > > I currently have a model-1 web application > > ie in which the .jsp pages are responsible > > for invoking the business logic. > > > > I am planning to move the webapp to struts, > > for all the obvious and traditional reasons. > > However, there is one nice feature of the > > current code that I can't see how to perform > > inside an MVC framework like struts: > > > > On submitting a particular form, there is a > > sequence of 4 operations to perform, each of > > which takes somewhere between 5 and 30 > > seconds to perform. Currently, what is done is > > to generate an almost complete HTML page, > > and force it to be flushed to the browser; as > > each long-duration step starts and completes, > > a fragment of page containing CSS-positioned > > html/ javascript is flushed to the browser. The > > effect is very nice - a list of the steps appears > > on the screen, an hourglass appears next to > > each step as it starts, and a tick or error message > > appears next to each one as it completes. > > > > Does anyone have any idea how to generate the > > same sort of effect (essentially alternating between > > business logic and presentation output) in struts? > > > > Thanks in advance, > > > > Simon > > How about creating a separate thread to perform the tasks, and > forwarding immediately to the jsp page in your main thread. Create an > object which can wait for the tasks to complete, and attach that object > to the request before forwarding. > > As an example, create a TaskMonitor (sample code below; this code is > untested, and I usually don't program threads so don't trust it to work > without some scrutiny). > > Task thread. Create a thread to perform your tasks and give it a > reference to this monitor. Each time a task is complete, call > monitor.taskComplete(taskid). > > Main thread. Attach monitor to request. Forward to jsp. The jsp can > call monitor.waitForTask(taskid) for each task in sequence. > > public class TaskMonitor { > > boolean[] taskComplete; > > public TaskMonitor(int taskCount) { > taskComplete = new boolean[taskCount]; > } > > public synchronized waitForTask(int taskid) { > if (taskid < 0 || taskid >= taskComplete.length > || taskComplete[taskid]) return; > while(true) { > try { > wait(); > } > catch(InterruptedException ie) { } > if (taskComplete[taskid]) return; > } > } > > public synchronized taskComplete(int taskid) { > if (taskid > 0 && taskid < taskComplete.length) { > taskComplete[taskid] = true; > notifyAll(); > } > } > > }