web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Batch jobs, dependencies & tasks that "didn't run"

(0) ShareShare
ReportReport
Posted on by

I have a scheduled job that populates a number of "denormalised" tables to present a simplified data structure for OData exposure so end users can write their own 'reports' in Excel.  There are a number of these tables, with some tables benefiting from the aggregations performed in the population of earlier tables, so my approach to this has been to construct a batch controller task that

  • instantiates a class to populate each table
  • adds a task to the batch header using that population class
  • creates dependencies between tasks

The issue I'm seeing is that tasks with multiple dependencies get left with a status of Didn't run, despite their dependencies Actual status appearing to meet the Expected status:

2620.BatchTaskDependencies.png

I've not managed to find much in the way of reference material for this status: there's one thread with no replies, and one with no definitive advice, so in case this description doesn't mean anything to people, the screenshot above of the batch job from comes from a minimal XPO I've put together.  Relevant section of the controller class (pretty much all of it) is:

RunBaseBatch        batchTask, postTask;
Set                 preReqTasksOne, preReqTasksTwo;
SetEnumerator       se;
preReqTasksOne = new Set(Types::Class);
preReqTasksTwo = new Set(Types::Class);

batchHeader = BatchHeader::construct(this.parmCurrentBatch().BatchJobId);
info(strFmt('%1 Batch header constructed', DateTimeUtil::utcNow()));

//Call construct method for another batch class.  Runtime tasks are removed on completion: most suitable for recurring tasks
//batchHeader.addRuntimeTask(LNPS_UnallocatedLedger_Populate::construct(), this.parmCurrentBatch().RecId);
//As opposed to Tasks that remain after completion: can be better for review/auditing
batchTask = LNPS_DependencyOne::construct();
batchHeader.addTask(batchTask, this.parmCurrentBatch().RecId);
preReqTasksOne.add(batchTask);
info(strFmt('%1 Task one added', DateTimeUtil::utcNow()));

batchTask = LNPS_DependencyTwo::construct();
batchHeader.addTask(batchTask, this.parmCurrentBatch().RecId);
preReqTasksTwo.add(batchTask);
info(strFmt('%1 Task two added', DateTimeUtil::utcNow()));

postTask = LNPS_DependentChild::construct();
batchHeader.addTask(postTask, this.parmCurrentBatch().RecId);
info(strFmt('%1 Child task added', DateTimeUtil::utcNow()));

//Enumerators are overkill in this instance where there's only one task in each set, but in true project, the prerequisite task has been split into multiple batch tasks for parallel execution
se = preReqTasksOne.getEnumerator();
while(se.moveNext())
{
    batchTask = se.current();
    batchHeader.addDependency(postTask, batchTask, BatchDependencyStatus::Finished);
}
info(strFmt('%1 Dependency set one added', DateTimeUtil::utcNow()));

se = preReqTasksTwo.getEnumerator();
while(se.moveNext())
{
    batchTask = se.current();
    batchHeader.addDependency(postTask, batchTask, BatchDependencyStatus::Finished);
}
info(strFmt('%1 Dependency set two added', DateTimeUtil::utcNow()));

info(strFmt('%1 All tasks added to batch header', DateTimeUtil::utcNow()));
batchHeader.save();

Any pointers to further reading material on the subject of dependencies, or specific advice on how I'm constructing my batch task, would be greatly appreciated.

*This post is locked for comments

I have the same question (0)
  • Mea_ Profile Picture
    60,284 on at
    RE: Batch jobs, dependencies & tasks that "didn't run"

    Hi Rich Hims,

    You probably mixed 2 methods. If you take a look at batchHeader.addRuntimeTask() you notice that second parameter is batch job recid and it makes sense there, but not for addTask(), because second parameter is enum.

  • Verified answer
    Community Member Profile Picture
    on at
    RE: Batch jobs, dependencies & tasks that "didn't run"

    Took another look at this, and spotted that the Condition type radio button set for the child task held no value.  Despite the fact that all examples of creating batch tasks in X++ I've seen use the same 

    batchHeader.addTask(postTask, this.parmCurrentBatch().RecId);

    syntax, it seems to me that the second parameter should use the BatchConstraintType enum.  In this instance, where there are two tasks that must both complete before the child task should start, the batch header task addition should be

    batchHeader.addTask(postTask, BatchConstraintType::And);

    Making this change has given me a 100% complete controller job, so I'd recommend this change to anyone, noting that the use of this.parmCurrentBatch().RecId is likely related to the addRuntimeTask method which requires an inheritFromTaskId parameter.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Andrés Arias – Community Spotlight

We are honored to recognize Andrés Arias as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Syed Haris Shah Profile Picture

Syed Haris Shah 9

#2
Mea_ Profile Picture

Mea_ 4

#3
Community Member Profile Picture

Community Member 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans