Adding runtime tasks to a business operation framework service

Hi all!

When I was at the technical conference in Nice last year, I attended the session about performance (BRK224), and during a demo, something interesting was shown: how to add one BOF service as a runtime task to another BOF service in batch.
You can watch the session recording here, the code is shown about 44 minutes, 50 seconds in.

Background: Runtime tasks in Dynamics AX 2009

If you are unfamiliar with runtime tasks and how to use them, read my post about batch multithreading for an explanation. The basic principle stays the same, but in the example below, we will be using the Business Operation Framework (aka BOF, aka SysOperation) instead of RunBaseBatch.

Runtime tasks in Dynamics AX 2012 using BOF

The first thing you’ll need to do, is create 2 BOF services, one that will create the runtime tasks, and one that will represent the runtime task. If you don’t know how to do that, read this post: SysOperation Introduction. You can download the xpo file for the following example below.

KlForSubTaskService: the runtime task

This service will be our runtime task. It’s a regular BOF service, nothing special about it. In my example, the service operation contains some testing code so we can see if our service is working:
class KlForSubTaskService
{
}

[SysEntryPointAttribute]
public void runSubTask(KlForSubTaskDataContract _klForSubTaskDataContract)
{
    info(strFmt("%1", _klForSubTaskDataContract.parmTheInt()));
}
The data contract for this service has one member:
[DataContractAttribute]
class KlForSubTaskDataContract
{
    Integer theInt;
}

[DataMemberAttribute]
public Integer parmTheInt(Integer _theInt = theInt)
{
    theInt = _theInt;

    return theInt;
}

KlForBatchJobService: Batch header service

This is the service that will create the runtime tasks. Starting for a regular BOF service, make sure that the service class extends SysOperationServiceBase. This enables us to call the isExecutingInBatch() method later on.
class KlForBatchJobService extends SysOperationServiceBase
{
}
The service operation that creates the runtime tasks looks like this:
[SysEntryPointAttribute]
public void createTasks()
{
    BatchHeader                    batchHeader;
    SysOperationServiceController  controller;
    KlForSubTaskDataContract       dataContract;

    int                             i;
    ;

    // for demo purposes, loop 10 times to add 10 runtime tasks
    for(i=1;i<=5;i++)
    {
        if(this.isExecutingInBatch() && !batchHeader)
        {
            // if no batchheader has been set yet, get it
            batchHeader = this.getCurrentBatchHeader();
        }

        // create new controller for the runtime task
        controller = new SysOperationServiceController(classStr(KlForSubTaskService), methodStr(KlForSubTaskService, runSubTask));

        // get the data contract
        dataContract = controller.getDataContractObject('_klForSubTaskDataContract');
        // initialize variables for the data contract
        dataContract.parmTheInt(i);

        if(this.isExecutingInBatch())
        {
            // code is running in batch, so add a runtime task
            batchHeader.addRuntimeTask(controller, this.getCurrentBatchTask().RecId);
        }
        else
        {
            // not in batch

            // by default, the tasks will execute in reliable asynchronous mode,
            // but you could override it so it executes synchronous
            //controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);

            // not in batch, just run it
            controller.run();
        }
    }

    if(batchHeader)
    {
        // save the batchheader if it has been created
        batchHeader.save();
    }

}
For this demo, I created a loop that creates 5 runtime tasks.
When you execute this in batch, you can check the batch task history for the batch to see the tasks that have been created.

You can click the Parameters button to verify if the correct values were used to execute the task.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.