Translation Quartz.net Framework Tutorial (Chinese Version) 2.2.x third lesson more about jobs and jobdetails

Source: Internet
Author: User

Lesson three more about jobs and jobdetails

In these two lessons we have learned that the jobs interface is very easy to implement, with only one execute method. We need to learn some more to understand the nature of jobs, the Execute method of the job interface, and the Jobdetails interface.

When you implement the Job interface class, Quartz requires you to provide the various parameters of the job instance, and the code in the job interface implementation class knows how to accomplish the specific job of the specified type job. This process is done through the Jobdetail class, which is briefly described in the next section.
The instance of Jobdetail is created by calling the Jobbuilder class. Usually you can use static import to get the call of all methods of the class, so that you can experience the sense of DSL in your code.

1 //define the job and tie it to our Hellojob class2Ijobdetail job = jobbuilder.create()3. Withidentity ("MyJob","group1")4     . Build ();5 6 //Trigger the job to run now, and then every seconds7Itrigger trigger =triggerbuilder.create ()8. Withidentity ("Mytrigger","group1")9   . Startnow ()Ten. Withsimpleschedule (x =x One. Withintervalinseconds ( +) A       . RepeatForever ()) -   . Build (); -  theSched. Schedulejob (Job, trigger);

The implementation class hellojob of the job interface can be defined like this

 1  public  class   Hellojob:ijob  2  3  public  void   Execute (Ijobexecutioncontext context)  4    " hellojob is executing.   "  6   7  }

Note that we provide a Jobdetail instance object to the scheduler, and when we build the Jobdetail object, we only provide the job's class object, and the scheduler knows the type of job it is going to perform. Each time the scheduler executes a job, it creates a new job instance before calling the Excecute method. When the call is complete, the associated Job object instance is freed, and the freed instance is reclaimed by the garbage collection mechanism. One result of this invocation process is that the jobs object must have a parameterless constructor (when using the default Jobfacotry implementation), and another result that the jobs implementation class cannot define state data fields because the values of these state data fields are not retained when the job task is invoked.

You may now want to ask "how can I provide configuration parameters for a job instance?" How do I track the status of a Job object when I perform a task? The answer to both questions is the same: use Jobdatamap, which is part of the Jobdetail object.

Jobdatamap

Jobdatamap can be used to load any serializable data object that is passed to it when the job instance object is executed. Jobdatamap implements the IDictionary interface and adds some very convenient methods to access the basic data types.

The following code snippet demonstrates how to store data in Jobdatamap before the Job object is added to the scheduler when the Jobdetail object is defined/built:

1Ijobdetail job = jobbuilder.create<dumbjob>()2. Withidentity ("MyJob","group1")//name "MyJob", Group "group1"3. Usingjobdata ("jobsays","Hello world!")4. Usingjobdata ("Myfloatvalue",3.141f)5. Build ();

The following example shows how to fetch data from a jobdatamap during job execution:

1  Public classDumbjob:ijob2 {3      Public voidExecute (jobexecutioncontext context)4     {5Jobkey key =context. Jobdetail.key;6 7Jobdatamap DataMap =context. Jobdetail.jobdatamap;8 9       stringJobsays = datamap.getstring ("jobsays");Ten       floatMyfloatvalue = Datamap.getfloat ("Myfloatvalue"); One  AConsole.Error.WriteLine ("Instance"+ key +"of Dumbjob says:"+ Jobsays +", and Val is:"+myfloatvalue); -     } -}

If you use persisted jobstore (which will be discussed in the tutorial Jobstore section), you should consider more of the data objects placed in Jobdatamap because the objects are serialized at this time, so this is more prone to versioning problems. Obviously the official version of the class is safe, but unofficial version, any time someone changes your order to instantiate the class definition, you should be careful not to break the compatibility. More information on this topic can be found in the Java Developer Connection Technical tips: serialization in the Real World. Of course, you can choose to design Jdbc-jobstore and Jobdatamap as only the base data type and the string type are allowed to store the map object, thus eliminating the problem of serialization fundamentally

If you add a setter method to the job class that corresponds to the key value of the Jobdatamap (for example, the Setjobsays (String val) method corresponds to the jobsays data in the example above), The default Jobfactory implementation class of the quartz framework calls these setter methods automatically when the job instance object is initialized, preventing the need to take the specified property value from the Map object when the execution method is called.

Triggers can also be associated with Jobdatamap objects, and when a Job object stored in the scheduler needs to be periodically/repeatedly executed and used by multiple triggers, it is very convenient to use JOBDATAMAP in this scenario, but for each individual trigger, you can provide different input parameters for the Job object.

Jobdatamap storage is very easy to obtain in Jobexecutioncontext when scheduling tasks. It integrates the Jobdatamap data objects in Jobdetail and trigger, and subsequent objects overwrite the values of the same key-value objects as the previous objects.

The following example shows the Jobdatamap data that was merged from Jobexecutioncontext during the execution of the task:

1  Public classDumbjob:ijob2 {3      Public voidExecute (ijobexecutioncontext context)4     {5Jobkey key =context. Jobdetail.key;6 7Jobdatamap DataMap = context. Mergedjobdatamap;//Note The difference from the previous example8 9         stringJobsays = datamap.getstring ("jobsays");Ten         floatMyfloatvalue = Datamap.getfloat ("Myfloatvalue"); Oneilist<datetimeoffset> state = (ilist<datetimeoffset>) datamap["Mystatedata"]; A State . ADD (Datetimeoffset.utcnow); -  -Console.Error.WriteLine ("Instance"+ key +"of Dumbjob says:"+ Jobsays +", and Val is:"+myfloatvalue); the     } -}

Or if you want to inject map data in a class that relies on jobfactory, you can refer to the following code:

1  Public classDumbjob:ijob2 {3      Public stringjobsays {Private Get;Set; }4      Public floatFloatvalue {Private Get;Set; }5 6      Public voidExecute (ijobexecutioncontext context)7     {8Jobkey key =context. Jobdetail.key;9 TenJobdatamap DataMap = context. Mergedjobdatamap;//Note The difference from the previous example One  Ailist<datetimeoffset> state = (ilist<datetimeoffset>) datamap["Mystatedata"]; - State . ADD (Datetimeoffset.utcnow); -  theConsole.Error.WriteLine ("Instance"+ key +"of Dumbjob says:"+ Jobsays +", and Val is:"+floatvalue); -     } -}

You may notice that the overall code for the class is longer, but the Execute method is concise. Some would argue that, while the code is long, if the programmer's Integrated development platform (IDE) automatically generates setter methods, less code can be written, rather than having to manually write those separate calling methods to take values from Jobdatamap. You can choose the way you write your own code.

Job "Instances"

Many users have doubts about the exact structure of the job instance object for a long time, and we will try to answer it here and tell you about the job status and concurrency mechanism in the next section.

you can create a separate job implementation class, create multiple different jobdetails instances, store different job instance definitions in the scheduler, and each jobdetails instance has its own parameters and Jobdatamap. and add these jobdetails to the scheduler.

For example: You create an implementation class for the job interface, the class name is "Salesreportjob", and the job class can pre-pass some hypothetical arguments (through Jobdatamap) to specify the salesperson's name in the sales report. Next, create a definition of multiple job instances (that is, jobdetails), such as "Salesreportforjoe" and "Salesreportformike" through "Joe" and "Mike" Specifies the input to the corresponding jobdatamaps as a parameter in the respective Job object.

When the trigger is triggered, the associated Jobdetail instance is loaded, and the associated job class is instantiated by the jobfactory configured in the scheduler, and the default jobfactory only calls the Newinstance method in the job class. Then try to call the setter method that matches the Jobdatamap key value. You can develop your own Jobfactory implementation classes to complete the creation and initialization of job instances by applying the IOC or di mechanism.

in the quartz framework, we call each stored jobdetail a job definition or jobdetail instance, which is called a job instance or a job definition instance. Usually we use only "job" words to correspond to named job definitions or Jobdetail. When we refer to the implementation class of the job interface, the term "job class" is generally used.
Job status and concurrency mechanism

Here are some additional information about job status values and concurrency. There is a pair of annotations added to the job class that can affect the behavior of these aspects of the quartz framework.

@DisallowConcurrentExecution annotations are added to the job class, which tells Quartz not to concurrently execute multiple instance objects created by the same job definition. Pay attention to the wording here, and be careful to choose. Referring to an example from the previous section, if Salesreportjob adds this annotation, only one Salesreportjobforjoe instance object can be executed within a given time period, but a salesreportjobformike instance may be executed concurrently. However, at the quartz design stage, you decide to carry annotations in this class, because the annotations affect the encoding of the Jobdetail class.

@PersistJobDataAfterExecution annotations are added to the job class, which tells Quartz to update the data stored in the Jobdetail jobdatamap after successful execution of the Execute method (except where exceptions are thrown). For example, the next execution of the same jobdetail will receive the updated value instead of the initial value. Similar to @disallowconcurrentexecution annotations, @PersistJobDataAfterExecution annotations apply to Job definition instances, not job class instances. Only the annotation is attached to the member variable of the job class, because it does not affect the encoding of the entire class (for example, statefulness only needs to be used correctly within the Execute method code).

If you use @persistjobdataafterexecution annotations, it is strongly recommended that you also consider using @disallowconcurrentexecution annotations, To avoid execution confusion when two identical jobdetail instances are executed concurrently, possibly due to inconsistent last storage state data.

Other properties of Jobs

Next, browse the other properties of the job instance, which are passed to the job instance through the Jobdetail object.

durability-If a job is non-persistent, the instance is automatically removed from the scheduler once there are no active triggers associated with the job instance. In other words, the life cycle of a non-persistent jobs is bounded by the presence of triggers.

requestsrecovery-If a job has a request recovery parameter set and is executing during the Scheduler Force shutdown (for example, a running thread crashes, or a server is down), it is re-executed when the scheduler restarts. In this case,the Jobexecutioncontext Isrecovery method returns true.

Jobexecutioinexception

Finally, we need to tell you some details of the Job.execute method. The only exception type that allows you to throw from the Execute method is jobexecutionexception (except run-time exceptions, which can be thrown normally), because of this limitation, you should wrap the exception to be handled in the Try-catch code block within the Execute method. You can also take some time to review the jobexecutionexception documentation to provide a variety of information to the scheduler when it is necessary to capture handling exceptions in the development job class.

Translation Quartz.net Framework Tutorial (Chinese Version) 2.2.x third lesson more about jobs and jobdetails

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.