Hi, On Wed, Feb 27, 2013 at 7:32 AM, Nigel Sheridan-Smith <wtfi...@gmail.com>wrote:
> Thanks Paul and Ernesto, > > After much stuffing around, I managed to get this to work: modifying the > JobDataMap within the Quartz job. However, you must re-publish the map > after it has been changed, as Quartz serializes it and doesn't update it > until after the job finishes executing. You might also need the > @PersistJobDataAfterExecution and @DisallowConcurrentExecution annotations > on the Quartz job to make it stateful. > > I remember using a quartz listener to attach/remove this "progress reporting class" to the Job... So that that progress class did not need to be stored. I don't remember if it was a thread local context like class.... > The callback: > > if (callback != null) { > > callback.updateProgress(resultSummary.successullyImportedRecords + > > resultSummary.unSuccessullyImportedRecords, false); > > } > > > > The updateProgress( ) callback on the Quartz job: > > public void updateProgress(int count, boolean error) { > > try { > > dataMap.put("results_counter", (int) count); > > dataMap.put("results_error", error); > > > > // Update the job detail and the associated data map (serialized in > > RAM?) > > TorScheduler.getScheduler().addJob(jobDetail, true); > > > > } catch (SchedulerException e) { > > e.printStackTrace(); > > logger.error("Error when updating the job details: " + e.getMessage()); > > } > > } > > > The Progress Bar within the Wicket page: > > > add(new AbstractAjaxTimerBehavior(Duration.seconds(3)) { > > private static final long serialVersionUID = 1L; > > @Override > > protected void onTimer(AjaxRequestTarget target) { > > TorSession session = TorSession.get(); > > progressbar.value(target, counter); > > JobKey jobKey = (JobKey) session.getAttribute( > > "importJobKey"); > > System.out.println ("job key: " + jobKey); > > > > boolean error = false; > > try { > > Scheduler scheduler = TorScheduler.getScheduler(); > > JobDetail jobDetails = scheduler.getJobDetail(jobKey); > > > > if (jobDetails == null) { > > System.out.println ("Job finished?"); > > PageParameters pp = new PageParameters().set("p", deck > > .getId().getTudi()); > > setResponsePage(Wiz14ImportComplete.class, pp); > > return; > > } > > > > JobDataMap jobDataMap = jobDetails.getJobDataMap(); > > > > counter = jobDataMap.getIntValue("results_counter"); > > error = jobDataMap.getBooleanValue("results_error"); > > > > } catch (SchedulerException e) { > > error("Error with import batch process: " + e.getMessage()); > > setUpdateInterval(Duration.NONE); > > target.add(curr); > > return; > > } > > > > if (error) { > > error("Error occurred during the import batch process"); > > setUpdateInterval(Duration.NONE); > > } else { > > // Redirect if we get the max count > > if (counter >= maxItems) { > > PageParameters pp = new PageParameters().set("p", deck > > .getId().getTudi()); > > setResponsePage(Wiz14ImportComplete.class, pp); > > } > > } > > > > target.add(curr); > > } > > }); > > > Cheers, > > Nigel > > > > > On Wed, Feb 27, 2013 at 5:14 PM, Ernesto Reinaldo Barreiro < > reier...@gmail.com> wrote: > > > Hi, > > > > I remember I have done this by creating a class that serves a "progress > > watching context" and sharing an instance of this class between Wicket > > Session (or a page or component) and the "quartz job". This class acted > as > > a "wire" to pass information between the two "threads" (e.g. progress, > > cancel the JOB, etc). I also used an AJAX timer too poll server. I think > > there is an example of how to do that at > > > > > > > http://code.google.com/p/antilia/source/browse/#svn%2Ftrunk%2Fcom.antilia.export%2Fsrc%2Fcom%2Fantilia%2Fexport%2Fpdf > > > > Thought code is quite old... > > > > > > On Tue, Feb 26, 2013 at 11:47 PM, Nigel Sheridan-Smith < > wtfi...@gmail.com > > >wrote: > > > > > Hi all, > > > > > > I'm hooking up a data import batch job with Quartz to Wicket and have > > > struck an issue - how do you notify a Wicket page that the batch job is > > > complete? > > > > > > I originally planned to update the Wicket session with the running > count > > of > > > how many items are processed. However, the Wicket request cycle expires > > so > > > it is not possible to update the session after the page is rendered. > > > > > > > > > To create the job: > > > > > > JobDataMap dataMap = new JobDataMap(); > > > > dataMap.put("service", getService()); > > > > dataMap.put("deck", deck); > > > > dataMap.put("importType", importType); > > > > dataMap.put("fieldMapping", fieldMapping); > > > > dataMap.put("fileUploaded", fileUploaded); > > > > dataMap.put("totalRecords", prevImportSummary.totalRecordsInImport); > > > > dataMap.put("callback", this); > > > > // Create a new job with a basic trigger > > > > JobDetail job = newJob(DataImportJob.class > > > > ).usingJobData(dataMap).build(); > > > > Trigger trigger = > > > > newTrigger().startNow().withSchedule(simpleSchedule()).build(); > > > > try { > > > > // Schedule the job for immediate start > > > > TorScheduler.getScheduler().scheduleJob(job, trigger); > > > > } catch (SchedulerException se) { > > > > TorScheduler.getLogger().error(se.getMessage()); > > > > throw new TorException("Cannot start the data import job"); > > > > } > > > > > > The data import job uses a callback to the Wicket page: > > > > > > callback.updateTotal(totalRecords); > > > > > > > callback.updateProgress(/* 0 */ totalRecords, false); // TODO: > > > > Temporarily skip the progress bar page > > > > > > > > > > > > > > // Now add the entries to the repository > > > > > > > ImportSummary importSummary = dataImportProcess.commit(callback); > > > > > > > callback.updateImportSummary(importSummary); > > > > > > > > > > The callback has this implementation (in the page): > > > > > > public void updateProgress(int count, boolean error) { > > > > > > > > // Attempt to reuse the same session as before (left open) > > > > > > > > session.setAttribute("importItemsDone", (Integer) count); > > > > > > > > session.setAttribute("importIsInError", (Boolean) error); > > > > > > > > } > > > > > > > > @Override > > > > > > > > public void updateTotal(int total) { > > > > > > > > > > > > // Attempt to reuse the same session as before (left open) > > > > > > > > session.setAttribute("importItemsTotal", (Integer) total); > > > > > > > > } > > > > > > > > > > > > @Override > > > > > > > > public void updateImportSummary(ImportSummary importSummary) { > > > > > > > > > > > > // Attempt to reuse the same session as before (left open) > > > > > > > > session.setAttribute("importSummary", importSummary); > > > > > > > > } > > > > > > > > > > However, I get this exception when attempting to update the Wicket > > session > > > with the progress counter: > > > > > > java.lang.IllegalStateException: Cannot set the attribute: no > > RequestCycle > > > available. If you get this error when using > > WicketTester.startPage(Page), > > > make sure to call WicketTester.createRequestCycle() beforehand. > > > at org.apache.wicket.Session.setAttribute(Session.java:773) > > > at > > > > > > > > > com.xxx.tor.webapp.profile.Wiz13ImportResults.updateTotal(Wiz13ImportResults.java:208) > > > at > > com.xxx.tor.webapp.batch.DataImportJob.importNow(DataImportJob.java:53) > > > at > com.xxx.tor.webapp.batch.DataImportJob.execute(DataImportJob.java:83) > > > at org.quartz.core.JobRunShell.run(JobRunShell.java:213) > > > at > > > > > > > > > org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) > > > > > > > > > Is this the best approach? Or should I attempt to use methods on the > > Quartz > > > scheduler to get the current progress of the batch job from within > > > AbstractAjaxTimerBehavior.onTimer( )? > > > > > > I am using the JQWicket (jQuery UI) progress bar... with a 5 second > delay > > > on updates to the page. > > > > > > Cheers, > > > > > > Nigel > > > > > > > > > -- > > > e: ni...@joinsomeone.com > > > m: +61 403 930 963 > > > > > > Get together for fun activities at www.joinsomeone.com > > > > > > Like us on Facebook www.facebook.com/JoinSomeone > > > Follow us on Twitter @JoinSomeone > > > > > > > > > > > -- > > Regards - Ernesto Reinaldo Barreiro > > Antilia Soft > > http://antiliasoft.com/ <http://antiliasoft.com/antilia> > > > > > > -- > e: ni...@joinsomeone.com > m: +61 403 930 963 > > Get together for fun activities at www.joinsomeone.com > > Like us on Facebook www.facebook.com/JoinSomeone > Follow us on Twitter @JoinSomeone > -- Regards - Ernesto Reinaldo Barreiro Antilia Soft http://antiliasoft.com/ <http://antiliasoft.com/antilia>