The Monarch Execution Context portion of the framework includes the ASNA.Monarch.Job class that supplements a process (or thread) in the implementation of the concept of a job. The Job class provides an environment for Monarch programs to run under. Its main functions are maintaining program activation and a connection to the database server. The Job class also provides facilities to support certain IBM i concepts, like when overriding file parameters or local data areas.
Programs
When an application is migrated from IBM i; each program
is transformed into an AVR class. In Monarch context, these
classes are still referred to as "Programs". A Program is a class that
conforms to certain conventions allowing it to be the target
of a
CALLB operation. The class has to implement
the
*Entry procedure (see topic below for more information). To
allow the retaining of state across program calls, the class
should derive from the
ASNA.Monarch.Program class that works in conjunction with
the
ASNA.Monarch.Job class.
Besides the
*Entry procedure, a Monarch program
typically has a
constructor and a
dispose subroutine. In the
constructor, the program opens all the files
that were marked as being implicitly opened, that is, those
not tagged as user controlled. The constructor is also
responsible for initializing any data structure subfields
requiring values other than zeros or blanks. The
dispose subroutine provides the opportunity
to close files and release any unmanaged resources.
The
Job maintains an
activation manager responsible for handling the activations of programs
according to the
ActivationGroup custom attribute defined in the
BegClass of the program. The ActivationGroup
attribute takes a string as a parameter that can be one of the following:
- Name – A user provided name identifying the activation group to use for the program.
- *Default – A predefined activation group called *Default. Programs not marked with an ActivationGroup attribute are allocated in this group.
- *New – This special value indicates that the program is to be run in a new activation group. Monarch will create a new unique name for the group.
- *Caller – This special value states that the program will be allocated in the same activation group as the program calling this program.
An example of the ActivationGroup attribute for each type
(highlighted bold) follows:
BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( "myGroupName" )) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( "*Default" )) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( "*New" )) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( "*Caller" ))
Instead of using hard-coded string literals for the special values, the class provides the following three constants:
- ActivationGroupAttribute.Caller
- ActivationGroupAttribute.Default
- ActivationGroupAttribute.New
An example using each of these is shown below:
BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( ActivationGroupAttribute.Default )) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( ActivationGroupAttribute.New )) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(ActivationGroup( ActivationGroupAttribute.Caller ))
Monarch also defines a couple of attributes to use as a
"shorthand" for the cases of *New and *Caller,
these are:
NewActivationGroupAttribute and
CallerActivationGroupAttribute. Using
this shorthand, you could code something like this
(both shown):
BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(NewActivationGroup()) BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public ) + Attributes(CallerActivationGroup ())
The "*Entry Procedure" figure in the next section shows a
program marked to run inthe activation group
"HardWater".
The *Entry Procedure
As part of the migration process of a program, Monarch
converts the mainline C-Specs into a procedure called *Entry in the generated class.
BegClass Custcalc Extends(ASNA.Monarch.Program Access( *Public ) +
Attributes(ActivationGroup("HardWater"))
. . .
DclFld Cust# Type ( *Packed ) Len( 9,0 )
DclFld Cust#Ch Type ( *Char ) Len( 9 )
DclFld SalesCh Type ( *Char ) Len( 13 )
DclFld ReturnCh Type ( *Char ) Len( 13 )
BegProc *Entry Access ( *Public )
DclSrParm Cust#Ch By ( *Reference ) Options( *NoPass )
DclSrParm SalesCh By ( *Reference ) Options( *NoPass )
DclSrParm ReturnCh By ( *Reference ) Options( *NoPass )
. . .
EndProc
The *Entry Figure above shows the generated *Entry. Notice how the Parms in the *ENTRY
PLIST become the parameters to the *Entry procedure.
MyJob
Each application has to be associated with a job. This is
achieved via the MyJob class that extends
ASNA.Monarch.Job. This class is generated by
Monarch and is available to be augmented. MyJob is
responsible for two main tasks: provide a connection to the
databases and invoke the startup program in the
application.
MyJob.MyDatabase and optionally MyJob.MyPrinterDB are defined in MyJob. MyDatabase is used for externally described data structures, for data file and data area access, and to call programs back on the server. MyPrinterDB is used to access print files. These database connections are used in two distinct forms; the commands refer to them to obtain their external definitions at compile time, and they are used at runtime to connect to the server.
When a program has to access the database at runtime, or any other of the members of the MyJob class or its base, it is necessary to obtain a reference to the instance associated with this job. This is done using the MonarchJob property provided by the base class ASNA.Monarch.Program. An example follows.
BegClass Custcalc Extends(ASNA.Monarch.Program Access( *Public ))
. . .
BegConstructor Access ( *Public )
. . .
Open CSMASTERL1 DB (MonarchJob.Database)
Open CMMASTERL1 DB (MonarchJob.Database)
EndConstructor
As we will see in a later chapter, web applications are
run in a multi-threaded environment, the
MonarchJob property gets the instance object of the
MyJob class associated with the particular thread running the
program.
The
MonarchJob property has a type of ASNA.Monarch.Job, if
you need to refer to members in the class that you added to
MyJob, then you should cast the value of MonarchJob
using the *AS operator. This example shows how to access a
field called MyField.
BegClass Custcalc Extends(ASNA.Monarch.Program) Access( *Public )
. . .
BegSr exampleSR Access( *Public )
DclFld X Type ( *Char ) Len( 10 )
X = (MonarchJob *AS MyJob).MyField
. . .
EndClass
Alternatively, you can use the Job's built-in LDC (local data collection) to provide access to objects and values to ASNA.Monarch.Program classes.
Startup Program
One of the main functions of
MyJob is to get the program call sequence going. This is done
by invoking the first program in the sequence of calls. This
is known as the
startup program.
A console program's My Job is
typically also responsible for processing the command
line. The following figure shows a MyJob sample where
the startup program called is CUSTPRTS.
BegClass MyJob Extends(ASNA.Monarch.Job) Access( *Public )
. . .
BegSr ExecuteStartupProgram Access( *Protected )
DclSrParm CustNumber Type ( *Char ) Len( 9 )
DclFld SendMsg Type ( *Char ) Len( 3 )
Connect MyDatabase
Connect MyPrinterDB
Move 'NO ' SendMsg
Call CUSTPRTS
DclParm CustNumber
DclParm SendMsg
EndPrograms()
EndSr
BegSr Main Shared(*Yes) Access(*Public)
DclSrParm Args Type(*String) Rank(1)
DclFld job Type(MyJob) New()
checkParms(Args)
job.ExecuteStartupProgram(Args[0])
EndSr
EndClass
The Main subroutine receives the parameters from the
command line in the
Args array. After being validated, the job's
ExecuteStartupProgram is called passing the first
argument as a parameter. In this case it represents a
customer number. The
ExecuteStartupProgram routine connects to the databases
and invokes the CUSTPRTS program. When CUSTRPRTS (and all the
programs it calls) end, the
EndPrograms method of
ASNA.Monarch.Job is called to deactivate any
program that is still active and then the Dispose method of
ASNA.Monarch.Job is called. This method is typically
overwritten to close databases and release any other resource
kept by the job.
Additional Embedded SQL Code
The following MyJob.vr shows a typical program with the
additional code highlighted for the SQL connection
established for processing embedded SQL. Notice the
/Error statements
generated as a reminder to change the code if MS SQL Server
is used.
For additional detail and other Monarch Framework classes that support embedded SQL, refer to SQL Migration Overview.
Using System
Using MyCompany.MyApplication
DclNamespace MyCompany.MyApplication.GroupAll_Job
BegClass MyJob Extends(ASNA.Monarch.WebJob) Access(*Public)
DclDB Name(MyDatabase) DBName("*Public/DG NET Local")Access(*Public)
DclDB Name(MyPrinterDB) DBName("DG Net Local")Access(*Public)
// additional declarative
DclFld ADO_Connection Type(System.Data.Odbc.OdbcConnection) Access(*Public)
/Error When using MS SQL Server, replace System.Data.Odbc.OdbcConnection with +
/System.Data.SqlClient.SqlConnection
BegFunc getDatabase Type(ASNA.isualRPG.Runtime.Database) Access(*Protected) Modifier(*Overrides)
LeaveSR MyDatabase
EndFunc
BegFunc getPrinterDB Type(ASNA.isualRPG.Runtime.Database) Access(*Protected) Modifier(*Overrides)
LeaveSR MyPrinterDB
EndFunc
// additional property
BegFunc getADO_Connection Type(System.Data.Common.DbConnection) Access(*Protected) Modifier(*Overrides)
LeaveSR ADO_Connection
EndFunc BegSr Dispose Access(*Public) Modifier(*Overrides)
DclSrParm disposing Type(*Boolean)
If disposing
Disconnect MyDatabase
Disconnect MyPrinterDB
// additional dispose of ADO_Connection
ADO_Connection.Close()
ADO_Connection.Dispose()
EndIf
*Base.Dispose(Disposing)
EndSr
BegSr ExecuteStartupProgram Access(*Protected) Modifier(*Overrides)
Connect MyDatabase
Connect MyPrinterDB
// additional code for ExecuteStartupProgram for the ADO connection
DclFld connectStr Type(*String)
connectStr=string.Format("Driver={{ClientAccessODBCDriver(32-bit)}}; +
"++"System={0};DBQ={1},*USRLIBL;Uid={2};Pwd={3}", +
MyDatabase.Server, +
MyDatabase.DBName, +
MyDatabase.User, +
/* Add your password here */ )
/Error When using MS SQL Server, replace connectStr assignment with "Data Source={0};Initial +
Catalog={1};Integrated Security=True"
ADO_Connection = *New System.Data.Odbc.OdbcConnection( connectStr )
/Error When using MS SQL Server, replace *New System.Data.Odbc.OdbcConnection with *New System.Data.SqlClient.SqlConnection
ADO_Connection.Open()
CallD 'MyCompany.MyApplication.Db0720'
EndSr
EndClass
CLProgram
Usage of CL can be divided into two major categories: System Administration and Application Coordination.
The administration of the system involves operations like the creation of user profiles and the save/restore procedures. These activities are not considered part of the application itself and Monarch does not attempt to facilitate such activities. Normal Windows® techniques should be employed to affect these kinds of activities.
CL is used to setup the environment for RPG programs to run. The Monarch Framework, through CL Program class, provides support for CL program procedures in these areas:
- Sets up the Library List. The Library List is an ordered set of directory names associated with each application's database connection.
- Overrides database file. File Overrides
are commands to replace the database file named in a CL
procedure or program or to change certain parameters of the
existing database file. These overrides can be applied to
DBFile,PrintFile, or aWorkStnFileobject. This may be especially useful for files that have been renamed or moved since the procedure or program was created. It can also be used to access a file member other than the first member. - Maintain application parameters in data
area. This covers several areas.
A local data area is created for each job in the system. The system creates a local data area, which is initially filled with blanks, with a length of 1024 and type*CHAR. When you submit a job, the value of the submitting job's local data area is copied into the submitted job's local data area. You can use this local data area to pass information to a procedure or program without the use of a parameter list.
Associated with each job are a set of job properties or attributes. These attributes can be programmatically accessed in CL via theRTVJOBAcommands. Another of these attributes is a series of 8 switches that can be "on" or "off." RPG programs also have access to these switches via the*INUxindicators.
Next: Display File Concepts
Previous: Control Execution Context
See Also
SQL Migration Overview
Job Class
Job.Database Property
Job.PrinterDB Property
Program Class
CLProgram Class
ActivationGroupAttribute Class
NewActivationGroupAttribute Class
CallerActivationGroupAttribute Class
