Showing posts with label batch. Show all posts
Showing posts with label batch. Show all posts
Wednesday, May 8, 2019
Saturday, February 10, 2018
Why my batch job is still waiting?
You probably have compilation errors in CIL. Try to recompile full CIL.
Wednesday, November 16, 2016
Automate Error 351
From time to time we get the lovely CIL compilation Error:351. As suggested by many, for example, by André Arnaud de Calavon, we have to recreate XppIL folder with all its guts.
The sequence is the following (quotation)
1. Stop the AOS.
2. Rename the XppIL folder (C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\XppIL) to e.g. XppIL_old.
3. Start the AOS.
4. Perform a full CIL generation.
A new XppIL folder will be created when you start the AOS.
When the CIL has completed without problems, you can delete the renamed XppIL_old folder.
Clean and simple. However, I am too impatient to wait for the end of deleting this huge folder: Windows Explorer starts time estimation and it drags on.
So, I wrote two short batch files that can be run as administrator and spare your time and nerves.
First just to rename the existing folder.
@echo off
set folder="C:\Program Files\Microsoft Dynamics AX\60\Server\CHR_AX_DEV\bin\"
echo Rename %folder% XppIL to XppIL_old?
pause
c:
cd %folder%
ren XppIL XppIL_old
echo %folder%XppIL to has been renamed to XppIL_old
pause
Second to delete all the files in the 'backed up' folder and its subfolders with no questions and infolog, then to delete the folder itself. As it said here, they must work faster than just removing the folder.
The last remarque. Be sure that your service windows account running the AOS in question had Full permission to the C:\Program Files\Microsoft Dynamics AX folder and all its subfolders.
command line
@echo off set folder="C:\Program Files\Microsoft Dynamics AX\60\Server\CHR_AX_DEV\bin\XppIL_old\" echo Delete all the files from %folder% and remove the folder? pause del /f/s/q %folder% > nul rmdir /s/q %folder% echo Folder %folder% removed pause
The last remarque. Be sure that your service windows account running the AOS in question had Full permission to the C:\Program Files\Microsoft Dynamics AX folder and all its subfolders.
command line
Saturday, March 12, 2016
Multi thread parallelism and a dispatching table for finding a minimum
In my free time I enjoy by solving programming puzzles from Advent of Code website. Some of them are pretty simple, though others could be tricky, however, all of them are always witty. Of course, I do it in AX so that I could use as much its power as possible.
The day 4 Ideal Stocking Stuffer became a die-hard to me. And it is not because of its "business complexity" -- you simply need to find the lowest positive number producing an MD5 hash for a given secret code, so that such a hash, in hexadecimal, starts with at least five zeroes.
Honestly, I have a vague idea about MD5 hash math -- I just took a working example and injected it into my class.
The stumbling point here was calculation time. Even for the first part of the puzzle, which is always easier than than the second one, it took so much time that I started flirting with the idea to improve performance.
Wrapping the MD5 hash calculation method so that it could be run in CIL got it faster but not enough to be happy.
The next idea was batch task execution in parallel threads, like it is brilliantly explained by Ganas1 in four chapter blog series:
Batch Bundling
However, we need to find the lowest positive number; therefore, we do not know how many tasks must be created. (Let's assume that we are limited with the maximum of Int64)
My solution is the following.
I created a table, which is to centrally dispatch creating, executing, and stopping batch tasks based on a separate, sequentially assigned positive number ranges. So, for each batch task it keeps the assigned thread number, ranges, execution status and found results, if any.
The batch task generating class creates them for a given number of logical processors, four in my environment.
Each task checks the table for a found result. If it is already found in any range, it stops.
If not, it looks for the highest range from the table and than tries to add a new record. In case of success, it runs finding the lowest number in the given range.
If such a number is found in the current thread, this value becomes a new candidate only if there are no results found in the lower ranges and no any lower ranges still running.
Now blood runs faster: even the second part of the job did not give me a pause to get another beer from the fridge.
However, it is up to your judgement to set up the right range size and number of parallel tasks. The smaller a single step is, the more the transaction cost will be. And vice-versa, the larger the range is, the longer you need to wait the higher ranges tasks to finish: the total execution time is the longest task's.
This project comprises examples of the following techniques:
Happy AX mining!
The day 4 Ideal Stocking Stuffer became a die-hard to me. And it is not because of its "business complexity" -- you simply need to find the lowest positive number producing an MD5 hash for a given secret code, so that such a hash, in hexadecimal, starts with at least five zeroes.
Honestly, I have a vague idea about MD5 hash math -- I just took a working example and injected it into my class.
The stumbling point here was calculation time. Even for the first part of the puzzle, which is always easier than than the second one, it took so much time that I started flirting with the idea to improve performance.
Wrapping the MD5 hash calculation method so that it could be run in CIL got it faster but not enough to be happy.
The next idea was batch task execution in parallel threads, like it is brilliantly explained by Ganas1 in four chapter blog series:
Batch Bundling
However, we need to find the lowest positive number; therefore, we do not know how many tasks must be created. (Let's assume that we are limited with the maximum of Int64)
My solution is the following.
I created a table, which is to centrally dispatch creating, executing, and stopping batch tasks based on a separate, sequentially assigned positive number ranges. So, for each batch task it keeps the assigned thread number, ranges, execution status and found results, if any.
The batch task generating class creates them for a given number of logical processors, four in my environment.
Each task checks the table for a found result. If it is already found in any range, it stops.
If not, it looks for the highest range from the table and than tries to add a new record. In case of success, it runs finding the lowest number in the given range.
If such a number is found in the current thread, this value becomes a new candidate only if there are no results found in the lower ranges and no any lower ranges still running.
Now blood runs faster: even the second part of the job did not give me a pause to get another beer from the fridge.
However, it is up to your judgement to set up the right range size and number of parallel tasks. The smaller a single step is, the more the transaction cost will be. And vice-versa, the larger the range is, the longer you need to wait the higher ranges tasks to finish: the total execution time is the longest task's.
This project comprises examples of the following techniques:
- dynamic dialog creation on RunBaseBatch
- wrapping for execution in CIL
- execution time calc
- multiple batch task creation
- try-catch exception handling for concurrent table updating
- InteropPermission assertion
Happy AX mining!
Labels:
AX2012,
batch,
batch processing,
CIL,
hash,
InteropPermission,
optimization,
parallel computing,
RunBaseBatch
Wednesday, March 2, 2016
Infolog in batch task history using SysOperation framework
If you add tasks to a batch job using SysOperation framework, like the following:
You need to set Execution mode to Synchronous while initializing your service class controller.
[...] while (mapIterator.more()) { if (!batchHeader) { batchHeader = this.getCurrentBatchHeader(); } controller = wblDirPartyMergeTaskController::construct(); [...] if (batchHeader) { batchInfo = controller.batchInfo(); batchHeader.addRuntimeTask(controller, this.getCurrentBatchTask().RecId); } else { setPrefix(batchInfoStr); controller.parmExecutionMode(SysOperationExecutionMode::Synchronous); controller.run(); } mapIterator.next(); } if (batchHeader) { batchHeader.save(); } }
You need to set Execution mode to Synchronous while initializing your service class controller.
// class wblDirPartyMergeTaskController extends SysOperationServiceController public void new() { super(); // default for controllers in these classes is synchronous execution // batch execution will be explicitly specified. The default for // SysOperationServiceController is ReliableAsynchronous execution this.parmExecutionMode(SysOperationExecutionMode::Synchronous); this.parmOther(newValue); }Otherwise you will see nothing in bath tasks history infolog.
Friday, January 23, 2015
Breakpoint; in CIL code
I needed to debug batch processing in BatchRun.ServerGetTask() method.

It was a wrong idea to add breakpoint; instruction into a managed code. Of course, after stopping my AOS did not start anymore because of the error:
Just-In-Time debugging this exception failed with the following error: The operation attempted is not supported
The easiest way to recover this problem is to delete the forementioned instruction and recompile CIL, but I have not access to AOT X++ editor anymore.
Alternatevily, as described in How-To-Debug-Managed-Code-In-AX2012, I did catch this breakpoint in Visual Studio during the short period between Starting and Stopped statutes of AOS service.
Launch Visual Studio as administrator.

Open the class method in question directly frpm xppCIL\Source folder.


Start the AOS service.

Switch back to Visual Studio and attach to the process. It appeared in a few seconds.

Then it stopped at the problematic breakpoint.

Pressing F5 each time it stopped there (actually every minute, as it supposed to be for batch processing), I changed my code back and run full CIL.

Please, do not place breakpoint; in managed code like I did.
Full MSDN article about debugging in AX 2012.

It was a wrong idea to add breakpoint; instruction into a managed code. Of course, after stopping my AOS did not start anymore because of the error:
Just-In-Time debugging this exception failed with the following error: The operation attempted is not supported
The easiest way to recover this problem is to delete the forementioned instruction and recompile CIL, but I have not access to AOT X++ editor anymore.
Alternatevily, as described in How-To-Debug-Managed-Code-In-AX2012, I did catch this breakpoint in Visual Studio during the short period between Starting and Stopped statutes of AOS service.
Launch Visual Studio as administrator.

Open the class method in question directly frpm xppCIL\Source folder.


Start the AOS service.

Switch back to Visual Studio and attach to the process. It appeared in a few seconds.

Then it stopped at the problematic breakpoint.

Pressing F5 each time it stopped there (actually every minute, as it supposed to be for batch processing), I changed my code back and run full CIL.

Please, do not place breakpoint; in managed code like I did.
Labels:
aos,
AOT,
AX2012,
batch,
batch processing,
breakpoint,
debug,
Visual Studio
Thursday, May 29, 2014
How to update cross-reference in batch
As you can see in AX 2012 updating cross references is not a batch job any more. But is worth setting it up to be run automatically during the night.
There is the article on MSDN describing this subject but without a batch, and if it looks too complicated for you, as for me, I would suggest another way found on AXForum (in Russian).
Once you started cross-reference updating from the client, you can easily find this job in Batch Job menu.
As we can see it is xRefUpdateIL class used for this goal, that in turn runs UpdateAll method.
So, it is possible to create your own job or batchable class to run, but we can just change the recurrence and set up other parameters, like alerts, for the ended batch job and change then its status to Waiting.
The same is true for partial reference update, say, for certain tables and classes of a project.
Happy cross-reference updating!
There is the article on MSDN describing this subject but without a batch, and if it looks too complicated for you, as for me, I would suggest another way found on AXForum (in Russian).
Once you started cross-reference updating from the client, you can easily find this job in Batch Job menu.
As we can see it is xRefUpdateIL class used for this goal, that in turn runs UpdateAll method.
So, it is possible to create your own job or batchable class to run, but we can just change the recurrence and set up other parameters, like alerts, for the ended batch job and change then its status to Waiting.
The same is true for partial reference update, say, for certain tables and classes of a project.
Happy cross-reference updating!
Labels:
admin,
AX2012,
batch,
batch processing,
class,
cross-reference
Friday, January 10, 2014
Windows Admin Trick: How to restart Windows In a Remote Session
Found it useful to create a batch file:
@echo off
echo Shutting down in 10 seconds. Please type "shutdown /a" to abort.
cmd.exe /K shutdown /f /t 10 /r
Subscribe to:
Posts (Atom)