Scout/Concepts/Scheduler

From Eclipsepedia

< Scout‎ | Concepts
Revision as of 09:54, 6 March 2013 by Urs.beeli.sbb.ch (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Scout
Wiki Home
Website
DownloadGit
Community
ForumsBlogTwitter
Bugzilla
Bugzilla
Scout provides a scheduler to run jobs. 

Contents

Facts

  • The instance for the Job is created exactly once. Every run of a job is executed by that instance.
  • The timer (when to start) is hardcoded (see example).

Usage

  1. Derive a class from AbstractSchedulerJob
  2. implement a constructor calling super(groupId, jobId);
  3. implement / override execAcceptTick
  4. implement / override run
  5. In the ServerApplication you need something like
public class ServerApplication implements IApplication{
  public Object start(IApplicationContext context) throws Exception {
    //start the scheduler
    Scheduler scheduler=new Scheduler(Activator.getDefault().getBackendSubject(),ServerSession.class);
    scheduler.addJob(new LoadJobs());
//    scheduler.addJob(new FetchMailSchedulerJob());
    scheduler.addJob(new LdapSchedulerJob());
    scheduler.addJob(new UpdatePLAOrdersJob());
    scheduler.start();
    Activator.getDefault().setScheduler(scheduler);
    ...

Example

public class MyJob extends AbstractSchedulerJob {
  private static IScoutLogger s_logger =ScoutLogManager.getLogger(MyJob.class);
  private final static String groupId = "MyGroup";
  private final static String jobId = "MyJob";
  /**
   * <p><code>true</code> the job is currently running, <code>false</code> else&</p>
   * <p>Access needs to be guarded / synchronized by <code>this</code>, because it is possible, that the same reference to the job
   * is called twice.</p>.
   */
  private boolean m_running;
 
  public MyJob() {
    super(groupId, jobId);
  }
 
  @Override
  protected boolean execAcceptTick(TickSignal signal, int second, int minute, int hour, int day, int week, int month,
      int year, int dayOfWeek, int dayOfMonthReverse, int dayOfYear, int secondOfDay) {
    return (second==0 && minute%10==0); /* start every 10 minutes */
  }
 
  @Override
  public void run(IScheduler scheduler, TickSignal signal) throws ProcessingException {
    synchronized (this) {
      if (m_running) { /* prevent the job from being started twice */
        s_logger.warn("The Job " + getGroupId() + "." + getJobId() + " is already running, but should be started. Job was not started.");
        return;
      }
      m_running = true;
    }
    try {
      s_logger.info("Started scheduled job: " + getGroupId() + "." + getJobId() + ", process all PLA Orders.");
      IXYZService service = SERVICES.getService(IXYZService.class);
      try {
        service.doStuff();
      } catch (Exception e) {
        s_logger.error("Error in Job " + getGroupId() + "." + getJobId(), e);
      }
      s_logger.info("Finished scheduled job: " + getGroupId() + "." + getJobId() + ", process all PLA Orders");
    } finally {
      synchronized (this) {
        m_running = false;
      }
    }
  }
}

Permissions

If such a server job is scheduled before a user is logged in, you might see the following exception:

!ENTRY org.eclipse.minicrm.server 4 0 2012-12-03 15:15:35.902
!MESSAGE org.eclipse.minicrm.server.ServerSession.execLoadSession(ServerSession.java:52) attempted login by server
!ENTRY org.eclipse.osgi 4 0 2012-12-03 15:15:35.933
!MESSAGE Application error
!STACK 1
ProcessingException[ProcessingStatus[ERROR code=0 Unexpected java.lang.SecurityException: access denied]]
at org.eclipse.scout.commons.job.JobEx.throwOnError(JobEx.java:69)
at org.eclipse.scout.rt.server.services.common.session.ServerSessionRegistryService.newServerSession(ServerSessionRegistryService.java:61)
at org.eclipse.scout.rt.server.services.common.session.ServerSessionRegistryService.newServerSession(ServerSessionRegistryService.java:35)
at org.eclipse.scout.rt.server.scheduler.Scheduler.<init>(Scheduler.java:58)
at org.eclipse.scout.rt.server.scheduler.Scheduler.<init>(Scheduler.java:49)
at org.eclipse.minicrm.server.ServerApplication.start(ServerApplication.java:41)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
[snip]

This can be solved in ServerSession by letting the system user load a session before anyone is logged in:

  @Override
  protected void execLoadSession() throws ProcessingException {
    SQL.selectInto("SELECT PERSON_NR FROM PERSON WHERE UPPER(USERNAME) = UPPER(:userId) INTO :personNr");

    if (getPersonNr() == null && !getUserId().equals("server")) {
      logger.error("attempted login by " + getUserId());
      throw new ProcessingException("Unknown User: " + getUserId(), new SecurityException("access denied"));
    }
 
    logger.warn("created a new session for " + getUserId());
  }