wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

Extend the Replicator


One elegant way to improve perceived performance is to run computing task outside of user time. In Notes that is done using (scheduled) agents and scheduled replication (On mobile devices it is called PushMail ). When you have longer running tasks that only make sense when new data might have arrived, a scheduled agent doesn't make much sense.
Triggering a process "On Replication" is much preferable. Classic Notes agents don't have this ability, but the Notes full client can do that. Already today the replicator hosts not only classic Notes NSF replication, but also address sync and Activities sync. This type of extensions can easily be created using an Eclipse extension point:
  1. <extension point="com.ibm.notes.client.notesSync">
  2. <unit class="com.notessensei.demo.RunOnReplication"
  3. id="com.notessensei.demo.runonreplication"
  4. image="icons/replicate.gif"
  5. label="NotesSensei's Demo Replication">
  6. </unit>
  7. </extension>
There are a few caveats (besides designing an 32x32 icon) when building the class, but once you know them it is straight forward:
  • You either extend org.eclipse.core.runtime.jobs.Job or com.ibm.notes.java.api.util.NotesSessionJob
  • For both approached you must have a default constructor without parameter. Neither of classes you extend has one, but your implementation needs one
  • When subclassing Job you extend run() for NotesSessionJob you extend runInNotesThread(). The later has the advantage to have all the session handling completed, but you end with a dependency on Notes client code
  • While both methods provide an IProgressMonitor as parameter, your code needs to try to obtain the Notes specific one (see sample)
  • Keeping track of units of work is a pain, expecially when your tasks calls various modules with unknown number of steps. Luckily there is SubMonitor that allows to specify a set amount of "ticks" for a subtask that can then adjust them as needed (see example)
  • You should check IProgressMonitor.isCanceled() inside your code and terminate processing at the first possible point (without sacrificing data integrity) when encountered
Your class could look like this:
packagecom.notessensei.demo;

importorg.eclipse.core.runtime.IProgressMonitor;
importorg.eclipse.core.runtime.IStatus;
importorg.eclipse.core.runtime.QualifiedName;
importorg.eclipse.core.runtime.Status;
importorg.eclipse.core.runtime.SubMonitor;
importorg.eclipse.core.runtime.jobs.Job;

publicclass RunOnReplication extends Job {

publicstatic QualifiedName notesMonitor =new QualifiedName ("com.ibm.notes.client", "notesMonitor");

public RunOnReplication (){
super("NotesSensei's Demo");
}

@Override
protected IStatus run (final IProgressMonitor paramIProgressMonitor ){
// Get the NotesProgress monitor
IProgressMonitor monitor =((IProgressMonitor )this. getProperty(notesMonitor ));
if(monitor ==null){
monitor = paramIProgressMonitor ;
}
// Total number of ticks - shown as # of Docs in the Replicator
SubMonitor sMon = SubMonitor. convert(monitor );
sMon. beginTask("We get started", 100);
for(int i =0; i <10; i ++){
this. doSomething(sMon. newChild(10));
if(sMon. isCanceled()){
return Status. CANCEL_STATUS;
}
}
returnnew Status (Status. OK, "com.notessensei.demo.runonreplication", "All went fine");

}

privatevoid doSomething (SubMonitor sm ){
sm. beginTask("SubTask", 345);
// Here would be real work!
for(int i =0; i <345; i ++){
sm. worked(1);
if(sm. isCanceled()){
return;
}
}
sm. done();
}
}
As usual: YMMV

Posted by on 20 August 2013 | Comments (2) | categories: IBM Notes XPages

Comments

  1. posted by Paul Withers on Tuesday 20 August 2013 AD:
    Great blog post. Is there a way to set the scheduled task in the High Priority list on the replicator?
  2. posted by Stephan H. Wissel on Wednesday 21 August 2013 AD:
    As fas as I know you can't change the priority. I checked with the Activities plug-in and it didn't show it either.