|
|
Line 1: |
Line 1: |
− | {{ScoutPage|cat=Shared}} Scout provides a scheduler to run jobs.
| + | The Scout documentation has been moved to https://eclipsescout.github.io/. |
− | | + | |
− | == 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 ==
| + | |
− | | + | |
− | #Derive a class from <code>AbstractSchedulerJob</code>
| + | |
− | #implement a constructor calling <code>super(groupId, jobId);</code>
| + | |
− | #implement / override <code>execAcceptTick</code>
| + | |
− | #implement / override <code>run</code>
| + | |
− | #In the ServerApplication you need something like
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | 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);
| + | |
− | ...
| + | |
− | </source>
| + | |
− | | + | |
− | == Example ==
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | 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;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | </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.<init>(Scheduler.java:58)<br>'''at org.eclipse.scout.rt.server.scheduler.Scheduler.<init>(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 && !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>
| + | |