Using the Task Execution Framework (TEF), ConSol CM can perform various tasks which are not directly tied to or embedded in another script (like a workflow script, unit action, resource action, search action or another type of Admin Tool script) and which can be executed asynchronously. This can be used, e.g., for long-term system tasks which might cause a timeout when started within a regular ConSol CM script. The TEF tasks can be executed in an asynchronous manner. A new API has been added to ConSol CM (in version 6.9.4.0) in order to provide the TEF extensions. TEF scripts can be started (i.e., the TEF API is available in):
A task is stored as Admin Tool script of type Task (see Admin Tool Scripts). This script type is explained in the respective section below.
Figure 363: ConSol CM Task Execution Framework
The Task Executor is a ConSol CM module (a singleton with watchdog functionalities) which controls the execution of the tasks. The Task Executor scans the database for new scheduled tasks and uses its thread pool for the execution of the tasks which have to be executed at a certain point in time.
The task definition is stored in an Admin Tool script. Thus, for one task definition, usually one Admin Tool script is used.
A (scheduled) task, i.e., one single run of the task, can be started ...
In scripts, for every execution of a task, a task descriptor, i.e., an object of the class TaskDescriptor, is available. This task descriptor provides information like the task's progress or the start time of the task execution. Using the task descriptor, a newly-defined task can be executed immediately or can be scheduled for a later execution time. This can be applied in scripts. Please see section Programming with Tasks for programming details.
Every Admin Tool script of type Task has to implement the following methods. The method signatures are inserted automatically when a script of this type is created.
def onInitialize(taskDescriptor) {}
def onExecute(taskDescriptor) {}
def onError(taskDescriptor) {}
def onCancel(taskDescriptor) {}
//Test
def onInitialize(taskDescriptor) {
log.info("MyFirstTaskScript has been initialized!")
}
def onExecute(taskDescriptor) {
log.info("MyFirstTaskScript is executed")
try {
Thread.Sleep(300000)
} catch (Exception ex) {
log.info("ztztzt ...")
}
}
def onError(taskDescriptor) {
log.info("MyFirstTaskScript has thrown an error!")
}
def onCancel(taskDescriptor) {
log.info("MyFirstTaskScript has been cancelled!")
}
Code example 54: Admin Tool Script of Type Task
In the Admin Tool, navigation group Services, navigation item Task Execution, you can start tasks which have been defined as Admin Tool scripts before.
To be able to execute tasks, the system property start.groovy.task.enabled in module cmas-app-admin-tool has to be set to the value true. This property is not present in a default installation and has to be added manually.
Please note that if the system property start.groovy.task.enabled in module cmas-app-admin-tool is set to true, and thus if you, as an administrator, can execute tasks using the Admin Tool, you have to be absolutely sure what the task will be doing!!! Be aware of the risks involved with tasks which, for example, delete customer data or tickets and should only be executed via a workflow or Admin Tool script!
Figure 364: ConSol CM Admin Tool - Admin Tool task
To start a script, click on the Start button and select the name of the Admin Tool script from the drop-down menu Static script. All Admin Tool scripts of type Task will be listed here. Click on Start to execute the script immediately. It is not possible to schedule a task using the Admin Tool GUI. If the start should be delayed, this has to be implemented within the script, see Defining the (First) Execution Date.
When a task is running, a progress bar is shown. You can stop (cancel) the task using the Stop button.
Figure 365: ConSol CM Admin Tool - Running task in the Admin Tool
In the current ConSol CM version, only one type of task is available, the Groovy Task with a static script. This refers to the Admin Tool script which defines the task, as described in the previous section.
The Task Execution Service (Groovy class TaskExecutionService, a singleton) runs in the background and scans the ConSol CM database for tasks (DB table cmas_task_descriptor) with the status INITIALIZED. Like all ConSol CM services it is implicitly available as an object named taskExecutionService (see the following examples). When the start time of the task has been reached, the task is started.
All parameters for the new task, e.g., the start date of the task, have to be set using the task descriptor (Groovy class TaskDescriptor). The task descriptor will also provide information about the running task, like the task's progress.
Figure 366: Some TEF Groovy classes
GroovyTask groovyTask = new GroovyTask();
groovyTask.setStaticScript(scriptSourceService.getByName("someATScript.groovy"));
taskDescriptor = taskExecutionService.schedule(groovyTask, "task");
Code example 55: Creating a task descriptor
Part 1: Create the task descriptor and save its ID somewhere.
GroovyTask groovyTask = new GroovyTask();
groovyTask.setStaticScript(scriptSourceService.getByName("someATScript.groovy"));
taskDescriptor = taskExecutionService.schedule(groovyTask, "task");
def myTaskDescriptorId = groovyTask.getId()
//save this Id wherever it will be needed, e.g., in a different script which might be used to kill the task
Code example 56: Cancelling a task
Part 2: potentially used during the execution of the task:
taskExecutionService.cancel(myTaskDescriptorId)
If you set another execution date for a task after its job has completed, it will be rescheduled. This is accomplished from within the Admin Tool Task script, as demonstrated here.
def onInitialize(taskDescriptor) {}
def onExecute(taskDescriptor) {
//some code to execute
...........................
//here, we set the new future execution date for the task, we also need to return a special steering object
taskDescriptor.setExecutionDate(new Date(new Date().getTime() + 15000));
return new ExecutionSpecification().setRetryRequested(true);
}
def onError(taskDescriptor) {}
def onCancel(taskDescriptor) {}
Code example 57: Repeating a task
For a script which should not be started immediately, you can define a start time in the onInitialize() method.
def onInitialize(taskDescriptor) {
taskDescriptor.setExecutionDate(yourDate)
}
Code example 58: Scheduling a task
def onInitialize(taskDescriptor) {}
def onExecute(taskDescriptor) {}
def onError(taskDescriptor) {
return new ExecutionSpecification().setRetryRequested(true);
// this will reschedule the task for immediate re-execution, in case a future date is needed, this can be set as explained in the example above
def onCancel(taskDescriptor) {}
Code example 59: Repeating a task after an error occurred
Using the ContextReference, it is possible to determine which context a script has been called in. For example, a TEF script might be required to behave differently depending on whether it is called from a workflow script in a certain activity or in the process from another activity. In such cases, the ContextReference will help you to deduce which workflow script the TEF script was called from. You just set a different ContextReference, which is a simple string as identifier, in each workflow script. Then you can retrieve the ContextReference within the task. Thus the task "knows" where it was called from.
Use the methods
See also example #2 below.
In this example, a task script will be executed from a workflow activity. No delay is set, i.e., the task is scheduled to be executed immediately when the engineer executes the workflow activity using the Web Client. The script might then run in the background and the engineer will only see the results (like new ticket entries or new customer data) when the script is finished. No action is required on the engineer's part in between the script's start and completion.
Figure 367: ConSol CM Web Client - Workflow activity for task execution
Figure 368: ConSol CM Process Designer - Workflow activity for task execution
def myNewTask = new GroovyTask()
myNewTask.setStaticScript(scriptSourceService.getByName("MyFirstTaskScript"))
def myTaskDescriptor = taskExecutionService.schedule(myNewTask, "myTaskGroup")
myTaskDescriptor.setExecutionDate(new Date())
Code example 60: Workflow activity script for task execution
2015-02-20 11:54:24,742 INFO [rver.service.task.TaskExecutor] [task-executor-task-executor:10.0.6.200:0-] Task Executor task-executor:10.0.6.200:0 is executing task: TaskDesc-02-20 11:54:19.0, transactionTimeout (sec)=0, type=class com.consol.cmas.common.model.task.GroovyTask}
2015-02-20 11:54:24,747 INFO [ database_MyFirstTaskScript] [task-executor-task-executor:10.0.6.200:0-] MyFirstTaskScript is executed
2015-02-20 11:54:24,747 INFO [ database_MyFirstTaskScript] [task-executor-task-executor:10.0.6.200:0-] ztztzt ...
2015-02-20 11:54:24,748 INFO [rver.service.task.TaskExecutor] [task-executor-task-executor:10.0.6.200:0-] Task execution successful removing task : TaskDescriptor{group='myT, transactionTimeout (sec)=0, type=class com.consol.cmas.common.model.task.GroovyTask}
The Task script (Admin Tool script of type Task) will display the ContextReference from which it has been called.
Figure 369: ConSol CM Admin Tool - Admin Tool script for a TEF task
In different workflow activities, different ContextReferences are set as unique identifiers. When the TEF script is called, it will always display (in the log output) the ContextReference of the calling workflow activity.
Figure 370: Workflow activities and log output when one of the activities has called the TEF script
Module | Parameter | Default Value | Description |
---|---|---|---|
|
|
false |
Enables the "start task" button in the Admin Tool |
|
|
60 |
Sets the transaction timeout for the task execution service, i.e., one run of a task must finish before this timeout is reached |
|
|
1 |
Thread pool size, i.e., number of tasks executed in parallel |
|
|
5 |
Time to wait between execution of two tasks, in seconds |