Search code examples
axaptax++dynamics-ax-2012dynamics-ax-2012-r2sysoperationframework

SysOperation Framework suppress infolog messages for ReliableAsynchronous but keep them in batch history


I'm just getting my feet wet with the SysOperation framework and I have some ReliableAsynchronous processes that run and call info("starting...") etc.

I want these infolog messages so that when I look in the BatchHistory, I can see them for purposes of investigating later.

But they also launch to the client, from the batch. And I can tell they're from the batch because you can't double click on the infologs to go to the source. Is there someway to either suppress these from popping up on the user's screen and only show in the batch log?

EDIT with some code: User clicks a button on form action pane that calls an action menu item referencing a class.

In the class, the new method:

public void new()
{
    super();

    this.parmClassName(classStr(MyControllerClass));
    this.parmMethodName(methodStr(MyControllerClass, pickTransLines));
    this.parmExecutionMode(SysOperationExecutionMode::ReliableAsynchronous);

    // This is meant to be running as a batch task, so don't load syslastvalue
    this.parmLoadFromSysLastValue(false);
}

The main method hit from the menu item:

public static void main (Args _args)
{
    MyControllerClass           controller = new MyControllerClass();
    MyContract                  contract;
    WMSOrderTrans               wmsOrderTrans;
    RefRecId                    refRecId;

    if (_args && _args.dataset() == tableNum(WMSOrderTrans) && _args.record())
    {  
        contract = controller.getDataContractObject();
        contract.parmRefRecId(_args.record().RecId);
        controller.parmShowDialog(false);
        refRecId = controller.doBatch().BatchJobId;

        // This creates a batch tracking record
        controller.updateCreateTracking(refRecId, _args.record().RecId);
    }
}

The controller method that gets launched:

// Main picking method
private void pickTransLines(MyContract_contract)
{
    MyTrackingTable             tracking;
    boolean                     finished;
    BatchHeader                 batchHeader     = BatchHeader::getCurrentBatchHeader();
    boolean                     updateTracking  = false;

    // NOTE - This infolog launches after a few seconds to the user, but
    // you can't double click on the info message to go to the code
    // because it's fired from the batch somehow.
    info(strFmt("Working on wmsordertrans.recid == %1", _contract.parmRefRecId()));

    // Create/Update batch tracker if needed
    if (this.isInBatch())
    {
        // NOTE - This code gets executed so we ARE in batch
        this.updateTrackingStuff(...);
    }

    // Do the pick work
    finished = this.doPick(_contract);

    if(!finished)
        throw error("An error occurred during the picking process.");
}

Then a split second later this launches to my session: enter image description here


Solution

  • Look at the SysOperationServiceController.afterOperation method,:

    [...]
    if (_executionMode == SysOperationExecutionMode::ReliableAsynchronous)
    {
        batch = this.operationReturnValue();
        if (batch)
        {
            infolog.view(Batch::showLog(batch.RecId));
        }
    }
    [...]
    

    This is the code that shows the infolog to the screen for reliable asynchronous processed.

    You can create your own controller by extending SysOperationServiceController and use that on your menu item or in code, so do that and overwrite the afterOperation on your new controller, for example like this (didn't test but should work in your case):

    if (_executionMode != SysOperationExecutionMode::ReliableAsynchronous)
    {
        super(_executionMode, _asyncResult);
    }