Skip to main content
Jump to: navigation, search

Difference between revisions of "Scout/Concepts/Scheduler"

(Added system user permission addition)
 
Line 1: Line 1:
{{ScoutPage|cat=Shared}}
+
{{ScoutPage|cat=Shared}} Scout provides a scheduler to run jobs.  
Scout provides a scheduler to run jobs.
+
 
 +
== Facts  ==
  
== Facts ==
 
 
*The instance for the Job is created exactly once. Every run of a job is executed by that instance.  
 
*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).
 
*The timer (when to start) is hardcoded (see example).
Line 26: Line 26:
 
     Activator.getDefault().setScheduler(scheduler);
 
     Activator.getDefault().setScheduler(scheduler);
 
     ...
 
     ...
</source>
+
</source>  
 +
 
 +
== Example  ==
  
== Example ==
 
 
<source lang="java">
 
<source lang="java">
 
public class MyJob extends AbstractSchedulerJob {
 
public class MyJob extends AbstractSchedulerJob {
Line 76: Line 77:
 
   }
 
   }
 
}
 
}
</source>
+
</source>
 +
 
 +
== Permissions<br> ==
 +
 
 +
If such a server job is scheduled before a user is logged in, you might see the following exception:<br>
 +
<blockquote>
 +
''!ENTRY org.eclipse.minicrm.server 4 0 2012-12-03 15:15:35.902<br>!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<br>!MESSAGE Application error<br>!STACK 1<br>ProcessingException[ProcessingStatus[ERROR code=0 Unexpected java.lang.SecurityException: access denied]]<br> at org.eclipse.scout.commons.job.JobEx.throwOnError(JobEx.java:69)<br> at org.eclipse.scout.rt.server.services.common.session.ServerSessionRegistryService.newServerSession(ServerSessionRegistryService.java:61)<br> at org.eclipse.scout.rt.server.services.common.session.ServerSessionRegistryService.newServerSession(ServerSessionRegistryService.java:35)<br> at org.eclipse.scout.rt.server.scheduler.Scheduler.&lt;init&gt;(Scheduler.java:58)<br>'''at org.eclipse.scout.rt.server.scheduler.Scheduler.&lt;init&gt;(Scheduler.java:49)<br> at org.eclipse.minicrm.server.ServerApplication.start(ServerApplication.java:41)<br> '''at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)<br> [snip]'' <br>
 +
</blockquote>
 +
This can be solved in '''ServerSession''' by letting the system user load a session before anyone is logged in:<br>
 +
<pre>  @Override
 +
  protected void execLoadSession() throws ProcessingException {
 +
    SQL.selectInto("SELECT PERSON_NR FROM PERSON WHERE UPPER(USERNAME) = UPPER(:userId) INTO :personNr");
 +
 
 +
    if (getPersonNr() == null &amp;&amp; !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());
 +
  }
 +
</pre>

Latest revision as of 08:54, 6 March 2013


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

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());
  }

Back to the top