<?xml version="1.0" encoding="utf-8"?>
<AxClass xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>DEVTutorialBatchMultipleThread</Name>
<SourceCode>
<Declaration><![CDATA[
public class DEVTutorialBatchMultipleThread extends DEVTutorialBatchMultipleThreadBase
{
TransDate transDate;
DialogField dlgTransDate;
PositiveNumber taskSleepTimeMs;
DialogField dlgTaskSleepTimeMs;
PositiveNumber maxTaskCount;
DialogField dlgMaxTaskCount;
QueryRun queryRun;
#define.CurrentVersion(2)
#localmacro.CurrentList
transDate,
taskSleepTimeMs,
batchIdentifier,
maxTaskCount
#endmacro
}
]]></Declaration>
<Methods>
<Method>
<Name>dialog</Name>
<Source><![CDATA[
public Object dialog()
{
DialogRunbase dialog = super();
;
dlgTransDate = dialog.addFieldValue(extendedtypestr(TransDate), transDate);
dlgTaskSleepTimeMs = dialog.addFieldValue(extendedtypestr(PositiveNumber), taskSleepTimeMs, "Time to process 1 record(ms)");
dialog.addGroup("Performance settings");
dlgMaxTaskCount = dialog.addFieldValue(extendedtypestr(PositiveNumber), maxTaskCount, "Number of batch tasks", "Max number of tasks to create in batch job");
return dialog;
}
]]></Source>
</Method>
<Method>
<Name>getFromDialog</Name>
<Source><![CDATA[
public boolean getFromDialog()
{
;
transDate = dlgTransDate.value();
taskSleepTimeMs = dlgTaskSleepTimeMs.value();
maxTaskCount = dlgMaxTaskCount.value();
return super();
}
]]></Source>
</Method>
<Method>
<Name>initParmDefault</Name>
<Source><![CDATA[
public void initParmDefault()
{
this.initQuery();
taskSleepTimeMs = 100;
}
]]></Source>
</Method>
<Method>
<Name>initQuery</Name>
<Source><![CDATA[
public void initQuery()
{
Query query = new Query();
query.addDataSource(tablenum(CustTrans));
queryRun = new QueryRun(query);
}
]]></Source>
</Method>
<Method>
<Name>pack</Name>
<Source><![CDATA[
public container pack()
{
return [#CurrentVersion, #CurrentList, queryRun.pack()];
}
]]></Source>
</Method>
<Method>
<Name>unpack</Name>
<Source><![CDATA[
public boolean unpack(container _packedClass)
{
Version version = RunBase::getVersion(_packedClass);
container queryCon;
switch (version)
{
case #CurrentVersion:
[version, #CurrentList, queryCon] = _packedClass;
if (SysQuery::isPackedOk(queryCon))
{
queryRun = new QueryRun(queryCon);
}
else
{
this.initQuery();
}
break;
default:
return false;
}
return true;
}
]]></Source>
</Method>
<Method>
<Name>queryRun</Name>
<Source><![CDATA[
public QueryRun queryRun()
{
return queryRun;
}
]]></Source>
</Method>
<Method>
<Name>runStartTask</Name>
<Source><![CDATA[
public void runStartTask()
{
//1. data preparation
info(strFmt("%1 - Start operation", AifUtil::applyUserPreferredTimeZoneOffset(DateTimeUtil::utcNow())));
}
]]></Source>
</Method>
<Method>
<Name>runThreadTask</Name>
<Source><![CDATA[
public void runThreadTask()
{
//2. Query Processing
QueryBuildDataSource qBDS = queryRun.query().dataSourceTable(tablenum(CustTrans));
qBDS.addRange(fieldnum(CustTrans, RecId)).value(batchIdentifier);
while (queryRun.next())
{
CustTrans custTrans = queryRun.get(tablenum(CustTrans));
this.processRecord(custTrans);
}
}
]]></Source>
</Method>
<Method>
<Name>runFinalTask</Name>
<Source><![CDATA[
public void runFinalTask()
{
//3.final task
info(strfmt("%2 - %1 record(s) processed", SysQuery::countTotal(queryRun),
AifUtil::applyUserPreferredTimeZoneOffset(DateTimeUtil::utcNow())));
}
]]></Source>
</Method>
<Method>
<Name>getBatchIdentifiersRangeCon</Name>
<Source><![CDATA[
public container getBatchIdentifiersRangeCon()
{
container res;
QueryRun queryRunLocal = new QueryRun(queryRun.query());
QueryBuildDataSource qBDS = queryRunLocal.query().dataSourceTable(tablenum(CustTrans));
int totalRecords, curRecord, recordsPerBatch;
RecId fromRecId, toRecId;
qBDS.sortClear();
qBDS.addSortField(fieldnum(CustTrans, RecId));
qBDS.addRange(fieldnum(CustTrans, RecId)).value(batchIdentifier);
totalRecords = SysQuery::countTotal(queryRunLocal);
recordsPerBatch = maxTaskCount > 0 ? totalRecords div maxTaskCount : totalRecords;
if (! recordsPerBatch)
{
recordsPerBatch = 1;
}
while (queryRunLocal.next())
{
CustTrans custTrans = queryRunLocal.get(tablenum(CustTrans));
if (! fromRecId)
{
fromRecId = custTrans.RecId;
}
curRecord++;
toRecId = custTrans.RecId;
if ((curRecord mod recordsPerBatch) == 0)
{
res += SysQuery::range(fromRecId, toRecId);
fromRecId = 0;
curRecord = 0;
}
}
if (curRecord && fromRecId && toRecId)
{
res += SysQuery::range(fromRecId, toRecId);
}
return res;
}
]]></Source>
</Method>
<Method>
<Name>processRecord</Name>
<Source><![CDATA[
public void processRecord(CustTrans _custTrans)
{
//do some job using _custTrans and transDate
sleep(taskSleepTimeMs);
}
]]></Source>
</Method>
<Method>
<Name>showQueryValues</Name>
<Source><![CDATA[
public boolean showQueryValues()
{
return true;
}
]]></Source>
</Method>
<Method>
<Name>canRunInNewSession</Name>
<Source><![CDATA[
public boolean canRunInNewSession()
{
return false;
}
]]></Source>
</Method>
<Method>
<Name>construct</Name>
<Source><![CDATA[
public static DEVTutorialBatchMultipleThread construct()
{
return new DEVTutorialBatchMultipleThread();
}
]]></Source>
</Method>
<Method>
<Name>description</Name>
<Source><![CDATA[
static ClassDescription description()
{
return "Batch multiple threads";
}
]]></Source>
</Method>
<Method>
<Name>main</Name>
<Source><![CDATA[
public static void main(Args _args)
{
DEVTutorialBatchMultipleThread runObject = DEVTutorialBatchMultipleThread::construct();
;
if (runObject.prompt())
{
runObject.runOperation();
}
}
Comments
Post a Comment