OFBiz implementation of task scheduling and job operation mechanism

Source: Internet
Author: User
Tags current time date1 sleep

Absrtact: This paper analyzes how OFBiz realizes task scheduling, and how to make related configuration, which can be used as a reference.



OFBiz the class that performs the background task is in Org.ofbiz.service.job.

Jobpoller and Jobinvoker are the main two classes, one is responsible for querying the job that can be performed, and the other is performing a job task. The job class diagram is shown below.



1.Job Polling

When you create a jobmanager, an instance of Jobpoller is created. Jobpoller implements the Runnable interface, after which the thread is created
The JobManager has been polled to see if there is a job that needs to be executed if the prize is put into the queue.


Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/

--1 public synchronized void run () {
2 try {
3//wait seconds before the first poll
4 Java.lang.Thread.sleep (30000);
5} catch (Interruptedexception e) {
6}
7 while (isrunning) {
8 try {
9//Grab a list of jobs to run.
Ten list<job> polllist = Jm.poll ();
One//Debug.loginfo ("Received poll list from JobManager [" + polllist.size () + "]", module);
12
(Job job:polllist) {
if (Job.isvalid ()) {
Queuenow (Job);
+//Debug.loginfo ("Job [" + job.getjobid () + "] is queued", module);
17}
18}
//Note:using sleep instead of wait for stricter locking
Java.lang.Thread.sleep (Pollwaittime ());
The catch (Interruptedexception e) {
Debug.logerror (E, module);
At a stop ();
24}
25}
26}
27
The Queuenow method puts the job into the queue, and if there is a large number of jobs waiting to be executed in the queue, a certain number of threads are created to execute the job.


Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/

--1 public void queuenow (Job job) {
2 synchronized (run) {
6 run.add (Job);
7}
8 if (Debug.verboseon ()) debug.logverbose ("New Run Queue Size:" + run.size (), module);
9 if (run.size () > Pool.size () && pool.size () < MaxThreads ()) {
Ten synchronized (pool) {
if (Run.size () > Pool.size () && pool.size () < MaxThreads ()) {
calcsize int = (run.size ()/Jobsperthread ())-(Pool.size ());
int addsize = calcsize > MaxThreads ()? MaxThreads (): calcsize;
14
(int i = 0; i < addsize; i++) {
Jobinvoker IV = new Jobinvoker (this, invokerwaittime ());
Pool.add (iv);
18}
19}
20}
21}
22}

Jobinvoker is the executing thread that takes the job from the queue and executes it. Jobinvoker threads are not running all the time, running longer than a certain value (see the value of TTL in Serviceengine.xml) The thread stops and is removed from the pool. The Jobinvoker Run Method Job.exec () performs a specific task.


2.Job execution

The job class has an Exec method, and the user executes the service of the job. As in Genericservicejob, the Exec method is as follows:


Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/

--1 public void exec () throws Invalidjobexception {
2 init ();
3
4//No transaction is necessary since Runsync handles this
5 try {
6//Get the dispatcher and invoke the service via Runsync--'ll run all ECAs
7 Localdispatcher Dispatcher = Dctx.getdispatcher ();
8 map<string, object> result = Dispatcher.runsync (Getservicename (), GetContext ());
9
//Check for a failure
One-by-one Boolean isError = ModelService.RESPOND_ERROR.equals (Result.get (modelservice.response_message));
if (isError) {
String errormessage = (string) result.get (modelservice.error_message);
This.failed (New Exception (errormessage));
15}
16
if (requester! = null) {
Requester.receiveresult (result);
19}
20
* catch (Throwable t) {
//Pass the exception back to the requester.
if (requester! = null) {
Requester.receivethrowable (t);
25}
26
//Call the failed method
This.failed (t);
29}
30
//Call the Finish method
This.finish ();
33}
34
In performing a service execution, there is an Init method in the Persistedservicejob class where the Init method primarily generates the next executing task, if any. This means that each job is generated by the job that was executed at that time, according to what. The main is two variables: Tempexprid and Maxrecurrencecount,init methods:


Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/

--1 temporalexpression expr = null;
2 ...
3
4 if (expr = = null && utilvalidate.isnotempty (job.getstring ("Tempexprid"))) {
5 try {
6 expr = temporalexpressionworker.gettemporalexpression (This.delegator, job.getstring ("Tempexprid"));
7} catch (Genericentityexception e) {
8 throw new RuntimeException (E.getmessage ());
9}
10}
11
Temporalexpressionworker There is a maketemporalexpression method is very important, from this method can know how to configure temporalexpression Entity data, Of course to combine the Temporalexpressions class, which defines the details of the various configurations.

There are several tempexprtypeid:

DateRange
Dayinmonth
Dayofmonthrange
Dayofweekrange
Difference
Frequency
Intersection
Monthrange
Timeofdayrange
Union

For example, if you want the service to execute only once, you can configure the following:
<temporalexpression tempexprid= "RUNONCE" tempexprtypeid= "FREQUENCY" integer1= "1" integer2= "1"/>
<jobsandbox jobid= "Currencyratesynall" jobname= "Currency rate Synall" runtime= "2010-02-26 09:38:00.000" Servicename= "Currencyratesynall" poolid= "Pool" runasuser= "System" tempexprid= "RUNONCE" maxrecurrencecount= "0"/>

maxrecurrencecount= "0" means no repetition. Tempexprtypeid= "FREQUENCY" integer1= "1" integer2= "1" means to execute once a year. So a total execution once is over.

Every day execution can be configured like this:

<temporalexpression tempexprid= "midnight_daily" tempexprtypeid= "Time_of_day_range" string1= "20:00:00" string2= " 20:00:00 "/>
<jobsandbox jobid= "mailnotification" jobname= "Mail Notification Job" runtime= "2010-02-25 18:00:00.000" ServiceName = "Mailnotificantion" poolid= "Pool" runasuser= "System" tempexprid= "midnight_daily" maxrecurrencecount= "-1"/>

Maxrecurrencecount= "-1" means infinite loop down. Tempexprid= "midnight_daily" tempexprtypeid= "Time_of_day_range" string1= "20:00:00" string2= "20:00:00"/> Indicates that it is performed eight o'clock every night.

Once a month the task can be configured as follows:

<temporalexpression tempexprid= "Onceinmonth" tempexprtypeid= "FREQUENCY" date1= "2010-02-26 11:05:00.000" Integer1 = "2" integer2= "1"/>
<jobsandbox jobid= "Currencyratesyn" jobname= "Currency rate Syn" runtime= "2010-02-26 11:05:00.000" Servicename= " Currencyratesyn "poolid=" Pool "runasuser=" System "tempexprid=" Onceinmonth "maxrecurrencecount="-1 "/>

Tempexprtypeid= "FREQUENCY" date1= "2010-02-26 11:05:00.000" integer1= "2" integer2= "1" means once a month, time is date1 defined time, If you don't define DATE1, it's the current time.

The configuration here is quite flexible and well mastered.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.