Understanding The Job in ASNA QSys
Estimated reading time: 4 minutes
ASP.NET Core does not implement the concept of a Job like IBM i does. The closest is Session State, but it is not what the IBM i Developer Model expects.
ASNA.QSys.Runtime assembly provides a more suitable class in the namespace ASNA.QSys.HostServices called Job
.
ASNA.QSys Job
provides the following support:
- Local Data Area.
- Database, Printfile and ADO connection(s).
- IBM i Job-like attributes.
- Switch indicators.
- File Override management.
- Program Activation Groups
- Attention program support.
- Open Data-Path (Workstationfile Sharing).
ASNA.QSys Interactive Job
ASNA Monarch Base is a framework to allow RPG-like Applications to run on ASP.NET Core, which is based on Web technology.
The ASNA.QSys Interactive Job specialized for Web, is conveniently named WebJob
, or fully qualified:
ASNA.QSys.HostServices.WebJob : Job
In addition to the base Job
services, WebJob
allows Procedurally-Designed Programs to use Workstation files on a Web environment.
How does the WebJob allow Procedurally-Designed Programs to run?
Simply put, when a WebJob
starts, a new .NET Thread is allocated for the Procedural programs to run.
💡 An identifier for the
WebJob
instance is saved as part of ASP.NET Core Session State.
MyJob
All ASNA Monarch .NET Projects have a specialized class derived from ASNA.QSys Job
(interactive or batch).
ASNA Monarch Cocoon generates such class during migration and gives it the name MyJob
. (The namespace for this class is the namespace provided by the migrator).
The generated MyJob looks like the following code:
Click here to see Encore RPG version of MyJob.er
Here is a copy C# version of MyJob.cs:
using ASNA.QSys.Runtime;
using ASNA.DataGate.Common;
using System;
using ACME.SunFarm;
using ASNA.QSys.Runtime.JobSupport;
namespace ACME.SunFarmCustomers_Job
{
[ProgramIndicators(INLRName = "_INLR", INName = "_IN", INRTName = "_INRT")]
public partial class MyJob : InteractiveJob
{
protected Indicator _INLR;
protected Indicator _INRT;
protected IndicatorArray<Len<_1, _0, _0>> _IN;
protected dynamic _DynamicCaller;
public Database MyDatabase = new Database(<dbname>);
public Database MyPrinterDB = new Database(<printer-db-name>);
override protected Database getDatabase()
{
return MyDatabase;
}
override protected Database getPrinterDB()
{
return MyPrinterDB;
}
override public void Dispose(bool disposing)
{
if (disposing)
{
MyDatabase.Close();
MyPrinterDB.Close();
}
base.Dispose(disposing);
}
static MyJob()
{
Database.PrepareNameStore<MyJob>(NameStoreOptions.UseJsonDefaultPath);
}
public static MyJob JobFactory()
{
MyJob job = null;
job = new MyJob();
return job;
}
override protected void ExecuteStartupProgram()
{
Indicator _LR = '0';
MyDatabase.Open();
MyPrinterDB.Open();
_DynamicCaller.CallD(<entry-point>, out _LR);
}
public MyJob()
{
_IN = new IndicatorArray<Len<_1, _0, _0>>((char[])null);
_instanceInit();
}
void _instanceInit()
{
_DynamicCaller = new DynamicCaller(this);
}
}
}
Note:
<dbname>
,<printer-db-name>
and<entry-point>
are placeholders for actual string constants, depending on the Application configuration.
As you can see in the code, in addition to the services the base class InteractiveJob
provides, the Project’s Job (MyJob), adds support for:
- Indicators (100 of them)
- LR and RT indicators
- Instancing Database file and Printfile connections.
- Entry-point Procedural Program execution.
- Disposal of Database file and Printfile connections when Job ends.