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>

Reply via email to