. . .

Cron Jobs


Default Cron Jobs

In each module class, empty methods are generated for implementing cron tasks - that is, these methods are executed automatically at a specific time. Typically, things like periodic sync or cleanup tasks can be put in these methods.

public void onCronHourly( final String appName, final String system )
{
}
 
public void onCronDaily( final String appName, final String system )
{
}
 
public void onCronWeekly( final String appName, final String system )
{
}
 
public void onCronMonthly( final String appName, final String system )
{
}

The methods are executed as follows:

  • onCronHourly: every full hour (e.g. 8pm, 9pm, 10pm,...)

  • onCronDaily: every day at 3am

  • onCronWeekly: every week on Mondays, 3am

  • onCronMontly: on every first day of the month, 3am

Run CRON Hook in new Thread

By default all CRON hooks are called one after another. This means, when there are two modules with an implemented onCronHourly, and one module is used by 5 apps in 2 systems, and the other is used by 10 apps in 3 system, that's 5 x 2 + 10 x 3 = 40 calls that get executed one after another, which might take quite some time and the last call might not be on the full hour (e.g. 8 p.m.), but a couple of minutes later, depending on how long the previous calls were.

To speed things up you can set a flag which leads to the CRON hook being executed on a new thread. And you can also configure the amount of threads in the used thread pool.

  • The flag can be set in the @Module annotation in the main module class. The flag is called runCronInNewThread and the allowed value is a Boolean, so you can set it to true or false. Default is false.

  • The amount of threads can be set in the apiomat.yaml configuration file. The configuration is called cronThreads and the default value is 10.

If you upgraded your ApiOmat installation from an older version to 2.5.2 or newer, your existing modules need to be updated in order to contain the latest nativemodule-base library which contains the @Module annotation. Depending on your previous and new ApiOmat version you might need to follow this guide: Update your Native Module to the current version

Test and execute via Dashboard

On the native modules page in "My Modules" is a Cronjob section for every native module. There is a selectbox where every cron method is listed with its cron expression. If you click on execute, the selected cron will directly be executed.

images/download/attachments/61479837/CustomCronjobs.png

Custom Cron Jobs

With ApiOmat version 2.6.4 you are able to define your own custom cron method within your module classes. Those methods will be registered as interruptable jobs (which basically means that they will be interrupted if the server breaks down or your module gets undeployed or redeployed).

All you have to do is to use the new annotation @Cron to mark your custom cron method within your module class.
In order your cron-marked module methods get executed timebased you also need to specify the annotation parameters cronExpression and executeOnAllNodes.

Example:


@Cron( cronExpression = "0 0/5 * * * ?", executeOnAllNodes = true )
public void myCustomCronMethod( final com.apiomat.nativemodule.Request request )
{
final String moduleName = "MyModule";
final String appName = request.getApplicationName( );
final String system = request.getSystem( );
final String className = "TestSimpleClass";
final String query = "";
 
final IModel<?>[ ] findByNames = MyModule.AOM.findByNames( appName, moduleName, className, query, request );
[...]
}

Method Signature

The method signature of your custom cron method must have one and only one parameter of type com.apiomat.nativemodule.Request. Other parameters will lead into a compile exception.
Please check the java code documentation for more details.

Cron Expression

The first annotation parameter called cronExpression defines how often your method gets called.

To build your cron expression you can use a cron expression generator like https://www.freeformatter.com/cron-expression-generator-quartz.html .

Additionally visit the official documentation http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/tutorial-lesson-06.html to understand how cron expressions work.


Cron Execution every Second

The recommended minimum execution interval of cron jobs in ApiOmat is once per minute. If you want your custom cron method to be executed every second or every 30 seconds you need to enable the following apiomat.yaml configuration first.

yambas:
limits:
allowCronEverySecond: true

The ApiOmat Server needs to be restarted after changing this configuration. If not set the default value is false.

After that you need to modify your defined cronExpression.

@Cron( cronExpression = "0/30 * * * * ?", executeOnAllNodes = false )

Switching to second based cron execution may drain your system and can produce performance issues.

Execute on all Nodes

The second parameter of the cron annotation called executeOnAllNodes defines if your custom method should be executed on every ApiOmat cluster node (value = true) or only on the primary cluster node (value = false).

Threadpool size

Addtionally you are able to define the size of the threadpool of the cron job scheduler. The default value is 10. Practically only values between 1 and 100 are recommended. The threadpool size will be defined by the upper configuration called cronThreads like the following:

yambas:
cronThreads: 10

After changing the cronThread configuration your ApiOmat instance needs a restart.

Examples

Here are some custom cron job examples that replace the default cron job methods:

@Cron( cronExpression = "0 0 * * * ?", executeOnAllNodes = false )
public void onCronHourly( final com.apiomat.nativemodule.Request request )
{
// method that gets called every hour
}
@Cron( cronExpression = "0 0 3 ? * *", executeOnAllNodes = false )
public void onCronDaily( final com.apiomat.nativemodule.Request request )
{
// method that gets called every day on 03:00 AM
}
@Cron( cronExpression = "0 0 3 ? * ", executeOnAllNodes = false )
public void onCronWeekly( final com.apiomat.nativemodule.Request request )
{
// method that gets called every Monday on 03:00 AM
}
@Cron( cronExpression = "0 0 3 1 * ?", executeOnAllNodes = false )
public void onCronMonthly( final com.apiomat.nativemodule.Request request )
{
// method that gets called every first day of each month on 03:00
}