Application Subsystem development: Difference between revisions
(49 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
==Overview== | |||
<p>Although only a system manager can define a subsystem, the determination of a subsystem's options and components typically also involves the file manager and application developer. This | <p> | ||
<p>The Subsystem Management facility of Dictionary lets you define a collection of procedures to <var class="product">Model 204</var> as a subsystem and to assign certain characteristics to that subsystem. </p> | Although only a system manager can define a subsystem, the determination of a subsystem's options and components typically also involves the file manager and application developer. This page focuses on subsystem facility topics most relevant to the application developer:</p> | ||
<p> | |||
<p>The following table summarizes the advantages of subsystems over other | The Subsystem Management facility of Dictionary lets you define a collection of procedures to <var class="product">Model 204</var> as a subsystem and to assign certain characteristics to that subsystem. </p> | ||
===Advantages of subsystems=== | |||
<p> | |||
The following table summarizes the advantages of subsystems over other [[SOUL]] procedure applications: </p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 9: | Line 13: | ||
<th>Subsystems...</th> | <th>Subsystems...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Minimal end-user intervention </td> | <td nowrap>Minimal end-user intervention </td> | ||
<td>Require minimal knowledge of <var class="product">Model 204</var>. The end user need not know what files and procedures exist for the application. The subsystem is invoked simply by entering the subsystem name as a <var class="product">Model 204</var> command.</td> | <td>Require minimal knowledge of <var class="product">Model 204</var>. The end user need not know what files and procedures exist for the application. The subsystem is invoked simply by entering the subsystem name as a <var class="product">Model 204</var> command.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Driver facility </td> | <td>Driver facility </td> | ||
<td>Eliminate the need for user-written drivers containing conditional INCLUDEs based on a global variable. This driver facility leads to smaller, more modular procedures that are easier to maintain and enhance.</td> | <td>Eliminate the need for user-written drivers containing conditional INCLUDEs based on a global variable. This driver facility leads to smaller, more modular procedures that are easier to maintain and enhance.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Performance improvements </td> | <td nowrap>Performance improvements </td> | ||
<td>Improve performance by saving and reloading compiled | <td>Improve performance by saving and reloading compiled SOUL requests, called precompiled procedures. Depending upon how often precompiled procedures are included, 20-90% of the operating costs of a <var class="product">Model 204</var> application can be saved.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Error handling facilities </td> | <td>Error handling facilities </td> | ||
<td>Trap and handle <var class="product">Model 204</var> errors in a single, centralized routine. Each subsystem can have one error procedure that is invoked each time a <var class="product">Model 204</var> error occurs during that subsystem's processing. <var class="product">Model 204</var> provides facilities for determining the type of error that caused the error procedure to be invoked. </td> | <td>Trap and handle <var class="product">Model 204</var> errors in a single, centralized routine. Each subsystem can have one error procedure that is invoked each time a <var class="product">Model 204</var> error occurs during that subsystem's processing. <var class="product">Model 204</var> provides facilities for determining the type of error that caused the error procedure to be invoked. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Security facilities </td> | <td>Security facilities </td> | ||
<td> | <td>Allow or restrict access to the subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Parallel Query Option/204 compatibility </td> | <td>Parallel Query Option/204 compatibility </td> | ||
Line 34: | Line 44: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>The characteristics and components of a subsystem are defined to <var class="product">Model 204</var> by the system manager during a process called subsystem definition. The defined options and components are stored in the system file CCASYS. Once a subsystem has been defined, all Dictionary users can display the options and components through Dictionary. For more information about:</p> | ===Subsystem definition=== | ||
<p> | |||
The characteristics and components of a subsystem are defined to <var class="product">Model 204</var> by the system manager during a process called subsystem definition. The defined options and components are stored in the system file CCASYS. Once a subsystem has been defined, all Dictionary users can display the options and components through Dictionary. For more information about:</p> | |||
<ul> | <ul> | ||
<li>Displaying a subsystem definition, see the | <li>Displaying a subsystem definition, see [[System requirements for Application Subsystems#Overview of the Subsystem Management facility|Overview of the Subsystem Management facility]]. </li> | ||
<li>Defining subsystems that refer to remote files and scattered groups, see | <li>Defining subsystems that refer to remote files and scattered groups, see [[PQO: Scattered APSY subsystems#Client and service subsystems|PQO client and service subsystems]]. | ||
</li> | </li> | ||
</ul> | </ul> | ||
==Subsystem design components== | |||
<p>During subsystem definition, the components listed below can be defined. These components impact various aspects of subsystem design. The following table summarizes the required component designations. </p> | <p> | ||
During subsystem definition, the components listed below can be defined. These components impact various aspects of subsystem design. The following table summarizes the required component designations. </p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 50: | Line 63: | ||
<th>Subsystem design requires designation of...</th> | <th>Subsystem design requires designation of...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Command line global variable </td> | <td nowrap>Command line global variable </td> | ||
<td>(Optional) parameter global variable. The parameter global variable allows any parameters specified by a user during a subsystem login to be stored in this variable and retained when control is transferred to another subsystem. </td> | <td>(Optional) parameter global variable. The parameter global variable allows any parameters specified by a user during a subsystem login to be stored in this variable and retained when control is transferred to another subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Communication global variable and exit value </td> | <td>Communication global variable and exit value </td> | ||
<td>Communication global variable and exit value. The communication global variable is used to transfer control from one procedure to another. The exit value is used to leave the subsystem. Optionally, a reserved global variable is available for transferring control between subsystems. </td> | <td>Communication global variable and exit value. The communication global variable is used to transfer control from one procedure to another. The exit value is used to leave the subsystem. Optionally, a reserved global variable is available for transferring control between subsystems. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Error global variable </td> | <td>Error global variable </td> | ||
<td>Error global variable. If an error occurs while the subsystem is executing, a three-character error code is stored in this variable. This code can then be used by an error procedure to determine the action to be taken by the subsystem. </td> | <td>Error global variable. If an error occurs while the subsystem is executing, a three-character error code is stored in this variable. This code can then be used by an error procedure to determine the action to be taken by the subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Prefix designations </td> | <td>Prefix designations </td> | ||
<td>Two prefixes for procedure names. These prefixes allow <var class="product">Model 204</var> to determine whether a procedure can be saved in its compiled form for later evaluation. </td> | <td>Two prefixes for procedure names. These prefixes allow <var class="product">Model 204</var> to determine whether a procedure can be saved in its compiled form for later evaluation. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Processing components</td> | <td>Processing components</td> | ||
Line 71: | Line 89: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>A command line global variable allows you to store any parameters specified by an end user during a subsystem login and retain this information when control is transferred to another subsystem. The designation of a command line global variable is optional. | ==Command line global variable== | ||
<p> | |||
<p>The command line global variable is used in the following manner:</p> | A command line global variable allows you to store any parameters specified by an end user during a subsystem login and retain this information when control is transferred to another subsystem. The designation of a command line global variable is optional. </p> | ||
===Using the command line global variable=== | |||
<p> | |||
The command line global variable is used in the following manner:</p> | |||
<ul> | <ul> | ||
<li>A user logs into a subsystem by entering the subsystem name followed by the parameter information. The total length of the parameter information entered by the user can consist of as many as 255 characters. (The portion of the command line reserved for parameter information is discarded if no parameter information is defined.)</li> | <li>A user logs into a subsystem by entering the subsystem name followed by the parameter information. The total length of the parameter information entered by the user can consist of as many as 255 characters. (The portion of the command line reserved for parameter information is discarded if no parameter information is defined.)</li> | ||
<li>The portion of the input following the subsystem name is placed into a command line global variable, which then is available to the application program. For example: | <li>The portion of the input following the subsystem name is placed into a command line global variable, which then is available to the application program. For example: | ||
<p class="syntax">PAYROLL <span class="term">parameter1 parameter2</span> | <p class="syntax">PAYROLL <span class="term">parameter1 parameter2</span> | ||
</p> | </p> | ||
<p>is the command that logs the current user into the subsystem named PAYROLL. The string <i>parameter1 parameter2</i> is the subsystem command line and is made available to the application via a global variable. If CMDL is the name assigned to the command line global variable, the following statements:</p> | <p> | ||
is the command that logs the current user into the subsystem named PAYROLL. The string <i>parameter1 parameter2</i> is the subsystem command line and is made available to the application via a global variable. If CMDL is the name assigned to the command line global variable, the following statements:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
%CMD.LINE = $GETG('CMDL') | %CMD.LINE = $GETG('CMDL') | ||
%FIRST.PARM = | %FIRST.PARM = | ||
$ | $Substr(%CMD.LINE,1,$INDEX(%CMD.LINE,' ')-1) | ||
</p> | </p> | ||
<p>would assign the contents of the command line used to enter the subsystem to %CMD.LINE and the first parameter of the line to %FIRST.PARM. </p> | <p> | ||
would assign the contents of the command line used to enter the subsystem to %CMD.LINE and the first parameter of the line to %FIRST.PARM. </p> | |||
</li> | </li> | ||
</ul> | </ul> | ||
===Transferring control to another subsystem=== | |||
<p>The contents of command line global variables are not deleted when control is transferred from one subsystem to another. A request can set the contents of the command line global variable of the destination subsystem before transferring control to that subsystem. The effect is the same as if the parameters were entered on the user's terminal. </p> | <p> | ||
The contents of command line global variables are not deleted when control is transferred from one subsystem to another. A request can set the contents of the command line global variable of the destination subsystem before transferring control to that subsystem. The effect is the same as if the parameters were entered on the user's terminal. </p> | |||
<p>The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem. </p> | |||
===Impact of the UTABLE command=== | |||
<p> | |||
<p>A communication global variable lets you transfer control at two levels: </p> | The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem. </p> | ||
==Communication global variable== | |||
===Transferring control=== | |||
<p> | |||
A communication global variable lets you transfer control at two levels: </p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 103: | Line 133: | ||
<th>Control is transferred by a...</th> | <th>Control is transferred by a...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>One procedure to another </td> | <td>One procedure to another </td> | ||
<td>User-designated global variable.</td> | <td>User-designated global variable.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>One subsystem to another </td> | <td>One subsystem to another </td> | ||
Line 112: | Line 144: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>Subsystem procedures pass control from one to another through the use of the communication global variable. The communication global variable name for a subsystem is specified in the subsystem definition. Each subsystem procedure must set the value of the communication global variable to the name of the next procedure to be executed.</p> | ===Transferring control between procedures=== | ||
<p> | |||
<p>For example, the subsystem AUTOS has procedures PRE-MAIN.MENU and PRE-RPT.PGM and the communication global variable NEXT. | Subsystem procedures pass control from one to another through the use of the communication global variable. The communication global variable name for a subsystem is specified in the subsystem definition. Each subsystem procedure must set the value of the communication global variable to the name of the next procedure to be executed.</p> | ||
PRE-MAIN.MENU is currently executing and wants to pass control to | |||
====Example==== | |||
<p> | |||
For example, the subsystem AUTOS has procedures PRE-MAIN.MENU and PRE-RPT.PGM and the communication global variable NEXT. | |||
PRE-MAIN.MENU is currently executing and wants to pass control to | |||
PRE-RPT.PGM. Before PRE-MAIN.MENU finishes, the function $SETG is used to store procedure name PRE-RPT.PGM in NEXT:</p> | PRE-RPT.PGM. Before PRE-MAIN.MENU finishes, the function $SETG is used to store procedure name PRE-RPT.PGM in NEXT:</p> | ||
<p class="code">IF $SETG('NEXT','PRE-RPT.PGM') THEN ... | <p class="code">IF $SETG('NEXT','PRE-RPT.PGM') THEN ... | ||
</p> | </p> | ||
<p>After PRE-MAIN.MENU ends, <var class="product">Model 204</var> examines NEXT and begins executing PRE-RPT.PGM.</p> | <p> | ||
After PRE-MAIN.MENU ends, <var class="product">Model 204</var> examines NEXT and begins executing PRE-RPT.PGM.</p> | |||
<p>A subsystem is exited by setting the value of the communication global variable to the subsystem exit value. The exit value for the communication global variable is also specified in the subsystem definition. </p> | |||
<p>For the AUTOS subsystem used in the preceding example, the exit value of the communication global variable is defined as EXIT. To disconnect the user from the AUTOS subsystem after procedure PRE-RPT.PGM is finished executing, PRE-RPT.PGM assigns the exit value, EXIT, to the communication global variable, NEXT.</p> | ====Subsystem exit value==== | ||
<p> | |||
A subsystem is exited by setting the value of the communication global variable to the subsystem exit value. The exit value for the communication global variable is also specified in the subsystem definition. </p> | |||
<p> | |||
For the AUTOS subsystem used in the preceding example, the exit value of the communication global variable is defined as EXIT. To disconnect the user from the AUTOS subsystem after procedure PRE-RPT.PGM is finished executing, PRE-RPT.PGM assigns the exit value, EXIT, to the communication global variable, NEXT.</p> | |||
<p class="code">IF $SETG('NEXT','EXIT') THEN | <p class="code">IF $SETG('NEXT','EXIT') THEN | ||
. | . | ||
. | . | ||
. | . | ||
</p> | </p> | ||
<p>One subsystem can invoke another subsystem by transferring control from itself to another subsystem. To accomplish this, you must perform these steps:</p> | ===Transferring control between subsystems=== | ||
<p> | |||
One subsystem can invoke another subsystem by transferring control from itself to another subsystem. To accomplish this, you must perform these steps:</p> | |||
<ol> | <ol> | ||
<li>Set the communication global variable to the value XFER.</li> | <li>Set the communication global variable to the value XFER.</li> | ||
<li>Set the global variable XFER to the name of the subsystem to which control is being passed. | <li>Set the global variable XFER to the name of the subsystem to which control is being passed. </li> | ||
</ol> | </ol> | ||
<p>When the current procedure finishes executing, <var class="product">Model 204</var> disconnects the user from the old subsystem, transfers control to the new subsystem, and invokes the login procedure for the new subsystem. | <p> | ||
When the current procedure finishes executing, <var class="product">Model 204</var> disconnects the user from the old subsystem, transfers control to the new subsystem, and invokes the login procedure for the new subsystem. </p> | |||
<p>You should consider the following factors when coding logic for transferring control between two subsystems:</p> | |||
====Design considerations==== | |||
<p> | |||
You should consider the following factors when coding logic for transferring control between two subsystems:</p> | |||
<ul> | <ul> | ||
<li>The transfer always invokes the login procedure of the subsystem receiving control. For more information on the login procedure, refer to the discussion [[#Subsystem processing flow|Subsystem processing flow]].</li> | <li>The transfer always invokes the login procedure of the subsystem receiving control. For more information on the login procedure, refer to the discussion [[#Subsystem processing flow|Subsystem processing flow]].</li> | ||
<li>The destination subsystem must be active. The $SUBSYS function should be used to determine if the subsystem to which control is being transferred is active; refer to the discussion on [[#Subsystem procedure control functions|Subsystem procedure control functions]]. If the destination subsystem does not use the automatic start option, (see [[#Operating options|Operating options]]), the subsystem must be started before control is passed. </li> | <li>The destination subsystem must be active. The $SUBSYS function should be used to determine if the subsystem to which control is being transferred is active; refer to the discussion on [[#Subsystem procedure control functions|Subsystem procedure control functions]]. If the destination subsystem does not use the automatic start option, (see [[#Operating options|Operating options]]), the subsystem must be started before control is passed. </li> | ||
<li>The destination subsystem should not reset LGTBL if any parameters are passed in global variables. </li> | <li>The destination subsystem should not reset LGTBL if any parameters are passed in global variables. </li> | ||
<li>To return to the original subsystem, a global variable must be set to the name of the original subsystem. The communication global variable and the XFER global variable can then be used with the global variable that stores the subsystem name to return control to the original subsystem.</li> | <li>To return to the original subsystem, a global variable must be set to the name of the original subsystem. The communication global variable and the XFER global variable can then be used with the global variable that stores the subsystem name to return control to the original subsystem.</li> | ||
<li>The destination subsystem can return control to the procedure that the user was in when the user transferred. To do this, the subsystem must save the name of the procedure in a global variable. In addition, the login procedure must contain logic to return control to the procedure that the user was in.</li> | <li>The destination subsystem can return control to the procedure that the user was in when the user transferred. To do this, the subsystem must save the name of the procedure in a global variable. In addition, the login procedure must contain logic to return control to the procedure that the user was in.</li> | ||
<li>If the transferring subsystem is in test mode (see [[#Security options|Security options]]), the transferring subsystem stops after it passes control. The destination subsystem is not placed in test mode. | <li>If the transferring subsystem is in test mode (see [[#Security options|Security options]]), the transferring subsystem stops after it passes control. The destination subsystem is not placed in test mode. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>The following request in procedure PRE-SUB.MENU provides an example of subsystem transfer code. CREDIT and AUTOS are two defined subsystems with the automatic start option. (See [[#Automatic start|Automatic start]].) Subsystem CREDIT transfers control to AUTOS by setting NEXT (the communication global variable) to XFER and the global variable XFER to AUTOS. After the PRE-SUB.MENU procedure ends, the user is connected to AUTOS.</p> | ====Example==== | ||
<p> | |||
The following request in procedure PRE-SUB.MENU provides an example of subsystem transfer code. CREDIT and AUTOS are two defined subsystems with the automatic start option. (See [[#Automatic start|Automatic start]].) Subsystem CREDIT transfers control to AUTOS by setting NEXT (the communication global variable) to XFER and the global variable XFER to AUTOS. After the PRE-SUB.MENU procedure ends, the user is connected to AUTOS.</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
. | . | ||
Line 160: | Line 207: | ||
<b></b>*SELECTION = 4 INDICATES CHOICE OF AUTOS SUBSYSTEM | <b></b>*SELECTION = 4 INDICATES CHOICE OF AUTOS SUBSYSTEM | ||
<b></b>* | <b></b>* | ||
SEL.AUTOS: IF %CREDITMENU:SELECTION = 4 AND - | SEL.AUTOS: IF %CREDITMENU:SELECTION = 4 AND - | ||
$SUBSYS('AUTOS') =1 THEN | $SUBSYS('AUTOS') =1 THEN | ||
IF $SETG('XFER','AUTOS') OR - | IF $SETG('XFER','AUTOS') OR - | ||
Line 171: | Line 218: | ||
. | . | ||
. | . | ||
. | . | ||
</p> | </p> | ||
===Coding considerations=== | |||
<ul> | <ul> | ||
<li>Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.</li> | <li>Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.</li> | ||
<li>Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.</li> | <li>Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.</li> | ||
<li>To exit the subsystem, the communication global variable must be set to the exit value. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used. | <li>To exit the subsystem, the communication global variable must be set to the exit value. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>The name of the error global variable must be specified in the subsystem definition. Whenever an error is detected that is not trapped by an ON unit, <var class="product">Model 204</var> automatically sets the subsystem's error global variable to a value which indicates the type of error that occurred. </p> | ==Error global variable== | ||
<p> | |||
<p> | The name of the error global variable must be specified in the subsystem definition. Whenever an error is detected that is not trapped by an ON unit, <var class="product">Model 204</var> automatically sets the subsystem's error global variable to a value which indicates the type of error that occurred. </p> | ||
===Error code values=== | |||
<p> | |||
The "Error global variable values and reasons" table lists the error global variable values and their corresponding causes. Correct the cause of the error, and/or change your error procedure as discussed in [[#Error procedures|Error procedures]]. </p> | |||
<table> | <table> | ||
<caption>Error global variable values and reasons</caption> | <caption>Error global variable values and reasons</caption> | ||
Line 192: | Line 244: | ||
<th>Reason</th> | <th>Reason</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>ATN </td> | <td>ATN </td> | ||
<td>User pressed attention</td> | <td>User pressed attention</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>BUG </td> | <td>BUG </td> | ||
<td>Evaluation errors</td> | <td>Evaluation errors</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>CAN</td> | <td>CAN</td> | ||
<td>Request evaluation canceled due to invalid terminal I/O in error procedure after BUMP or inactive thread time out.</td> | <td>Request evaluation canceled due to invalid terminal I/O in error procedure after BUMP or inactive thread time out.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>CNT </td> | <td>CNT </td> | ||
<td>Counting errors</td> | <td>Counting errors</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>FIL - BROKEN </td> | <td>FIL - BROKEN </td> | ||
<td>Referenced file is not initialized, full, or physically inconsistent. Check the audit trail to determine the condition of the file. </td> | <td>Referenced file is not initialized, full, or physically inconsistent. Check the audit trail to determine the condition of the file. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>FIL - NOT OPEN </td> | <td>FIL - NOT OPEN </td> | ||
<td>Referenced file not open</td> | <td>Referenced file not open</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>GRP - FTBL </td> | <td>GRP - FTBL </td> | ||
<td>FTBL too small</td> | <td>FTBL too small</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>GRP - NOT OPEN </td> | <td>GRP - NOT OPEN </td> | ||
<td>Group not open</td> | <td>Group not open</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>GRP - TEMP FIELD </td> | <td>GRP - TEMP FIELD </td> | ||
<td>TEMP group field has wrong type (see [[#Restrictions for temporary and ad hoc groups in precompiled procedures|Restrictions for temporary and ad hoc groups in precompiled procedures]])</td> | <td>TEMP group field has wrong type (see [[#Restrictions for temporary and ad hoc groups in precompiled procedures|Restrictions for temporary and ad hoc groups in precompiled procedures]])</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>GRP - TEMP MISMATCH </td> | <td nowrap>GRP - TEMP MISMATCH </td> | ||
<td>TEMP group has wrong type</td> | <td>TEMP group has wrong type</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>INCLUDE MAX</td> | <td>INCLUDE MAX</td> | ||
<td>Maximum iterations value has been exceeded.</td> | <td>Maximum iterations value has been exceeded.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>HNG </td> | <td>HNG </td> | ||
<td>Phone hung up, connection lost</td> | <td>Phone hung up, connection lost</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>HRD </td> | <td>HRD </td> | ||
<td>Hard restart</td> | <td>Hard restart</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>REC </td> | <td>REC </td> | ||
<td>Record locking table filled up during the load of a | <td>Record locking table filled up during the load of a | ||
precompiled request</td> | precompiled request</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>RFR</td> | <td>RFR</td> | ||
<td>After several tries, an APSY failed to invoke a procedure, because the procedure is in the process of being refreshed.</td> | <td>After several tries, an APSY failed to invoke a procedure, because the procedure is in the process of being refreshed.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>SFT </td> | <td>SFT </td> | ||
<td>Soft restart</td> | <td>Soft restart</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>TBL - FSCB </td> | <td>TBL - FSCB </td> | ||
<td>FSCB too small</td> | <td>FSCB too small</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>TBL - NTBL </td> | <td>TBL - NTBL </td> | ||
<td>NTBL too small</td> | <td>NTBL too small</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>TBL - QTBL </td> | <td>TBL - QTBL </td> | ||
<td>QTBL too small</td> | <td>QTBL too small</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>TBL - STBL </td> | <td>TBL - STBL </td> | ||
<td>STBL too small</td> | <td>STBL too small</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>TBL - VTBL </td> | <td>TBL - VTBL </td> | ||
Line 279: | Line 352: | ||
</table> | </table> | ||
===Error procedures=== | |||
<p>An error procedure must test for different error conditions. The resulting value stored in the error global variable helps the application programmer determine the type of error that occurred.</p> | <p> | ||
An error procedure must test for different error conditions. The resulting value stored in the error global variable helps the application programmer determine the type of error that occurred.</p> | |||
<ul> | <ul> | ||
<li>For all error codes except ATN, the error procedure should avoid re-executing the procedure that caused the error; otherwise, the error recurs. </li> | <li>For all error codes except ATN, the error procedure should avoid re-executing the procedure that caused the error; otherwise, the error recurs. </li> | ||
<li>In most cases, the error procedure should display an informational message and set the global communication variable to the exit value. </li> | <li>In most cases, the error procedure should display an informational message and set the global communication variable to the exit value. </li> | ||
<li>If a HNG error code is indicated, all terminal I/O (such as PRINT, READ) is ignored. </li> | <li>If a HNG error code is indicated, all terminal I/O (such as PRINT, READ) is ignored. </li> | ||
<li>If a HNG, HRD, or SFT error code is indicated, no terminal I/O (such as PRINT or READ) should be attempted. Instead, send a message to the audit trail in an AUDIT statement that indicates the error code encountered. | <li>If a HNG, HRD, or SFT error code is indicated, no terminal I/O (such as PRINT or READ) should be attempted. Instead, send a message to the audit trail in an AUDIT statement that indicates the error code encountered. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>The communications global variable is ignored and disconnect processing completed when one of the following conditions occurs:</p> | ====Considerations for the communications global variable==== | ||
<p> | |||
The communications global variable is ignored and disconnect processing completed when one of the following conditions occurs:</p> | |||
<ul> | <ul> | ||
<li>Error is a soft restart, a hard restart, or a phone hang-up condition. | <li>Error is a soft restart, a hard restart, or a phone hang-up condition. | ||
<p>If you attempt to set the communications global variable to the name of another procedure, the procedure is not executed.</p> | <p> | ||
If you attempt to set the communications global variable to the name of another procedure, the procedure is not executed.</p> | |||
</li> | </li> | ||
<li>No error procedure is specified in the subsystem definition. | |||
<li>No error procedure is specified in the subsystem definition. | |||
</li> | </li> | ||
</ul> | </ul> | ||
<p>An example illustrating how a subsystem error procedure can test for different error conditions is provided in [[#Error procedure|Error procedure]]. </p> | <p> | ||
An example illustrating how a subsystem error procedure can test for different error conditions is provided in [[#Error procedure|Error procedure]]. </p> | |||
<p>You can use two types of procedures in a subsystem: </p> | |||
<ul> | ==Precompiled and non-precompiled procedures== | ||
<li><b>Precompiled procedure</b> | <p> | ||
You can use two types of procedures in a subsystem: </p> | |||
<ul> | |||
<li><b>Precompiled procedure</b> | |||
<p> | |||
The first time a precompilable procedure is invoked after a subsystem starts, it is compiled and stored for re-use. Because the compiler phase is bypassed each subsequent time the procedure is invoked (except as noted below), precompilation saves both CPU and elapsed time. Exceptions include the following:</p> | |||
<ul> | <ul> | ||
<li>The procedure is recompiled the first time it is invoked for each SCLASS. The new compilation is evaluated, then discarded. It does not replace the original stored compilation. </li> | <li>The procedure is recompiled the first time it is invoked for each SCLASS. The new compilation is evaluated, then discarded. It does not replace the original stored compilation. </li> | ||
<li>Further recompilations might be required due to temporary group differences. See [[#Recompiling precompiled procedures|Recompiling precompiled procedures]] for more on this. </li> | <li>Further recompilations might be required due to temporary group differences. See [[#Recompiling precompiled procedures|Recompiling precompiled procedures]] for more on this. </li> | ||
</ul></li> | |||
<li><b>Non-precompiled procedure</b> | |||
<p> | |||
A non-precompiled procedure is compiled each time it is invoked.</p></li> | |||
</ul> | </ul> | ||
< | <p> | ||
All procedures, whether precompiled or not, are invoked using the communication global variable.</p> | |||
===Defining prefixes=== | |||
<p>During subsystem definition, two prefixes must be defined. The first prefix identifies precompiled procedures; the second identifies non-precompiled procedures. All procedures that are included for the subsystem through the use of the communication global variable (such as the login and main processing procedures) must have names that begin with one of these prefixes.</p> | <p> | ||
During subsystem definition, two prefixes must be defined. The first prefix identifies precompiled procedures; the second identifies non-precompiled procedures. All procedures that are included for the subsystem through the use of the communication global variable (such as the login and main processing procedures) must have names that begin with one of these prefixes.</p> | |||
<p>Subsystem procedures can contain <var class="product">Model 204</var> commands, a request, multiple requests, continued requests, sections of User Language code (for example, subroutines), or any combination thereof. However, the form of the procedure affects whether the procedure can be precompiled and should be taken into account when the subsystem is designed. Restrictions for precompiled procedures are discussed in detail below.</p> | |||
===Contents of subsystem procedures=== | |||
<p>Server I/O can be reduced by allowing users executing shared precompiled procedures to use a shared version of QTBL. See | <p> | ||
Subsystem procedures can contain <var class="product">Model 204</var> commands, a request, multiple requests, continued requests, sections of User Language code (for example, subroutines), or any combination thereof. However, the form of the procedure affects whether the procedure can be precompiled and should be taken into account when the subsystem is designed. Restrictions for precompiled procedures are discussed in detail below.</p> | |||
<p><var class="product">Model 204</var> must ensure that all of the code compiled and saved for a request with the precompiled prefix is consistent for all loading users. To achieve consistency, <var class="product">Model 204</var> restricts the way in which certain features are used. </p> | |||
<p>Note the following restrictions for precompiled procedures when designing subsystem procedures:</p> | ===Shared versions of precompiled procedures=== | ||
<p> | |||
Server I/O can be reduced by allowing users executing shared precompiled procedures to use a shared version of QTBL. | |||
See [[Performance monitoring and tuning#Resident Request feature for precompiled procedures|Resident Request feature for precompiled procedures]]. </p> | |||
===Restrictions for precompiled procedures=== | |||
<p> | |||
<var class="product">Model 204</var> must ensure that all of the code compiled and saved for a request with the precompiled prefix is consistent for all loading users. To achieve consistency, <var class="product">Model 204</var> restricts the way in which certain features are used. </p> | |||
<p> | |||
Note the following restrictions for precompiled procedures when designing subsystem procedures:</p> | |||
<ul> | <ul> | ||
<li>Procedures must contain exactly one request. The last statement must be END or END MORE.</li> | <li>Procedures must contain exactly one request. The last statement must be END or END MORE.</li> | ||
<li>Requests cannot start with MORE.</li> | <li>Requests cannot start with MORE.</li> | ||
<li>Procedures that include multiple BEGIN/END blocks are not eligible for precompilation.</li> | <li>Procedures that include multiple BEGIN/END blocks are not eligible for precompilation.</li> | ||
<li>Requests must not refer to files or permanent groups that are not mentioned in the subsystem definition.</li> | <li>Requests must not refer to files or permanent groups that are not mentioned in the subsystem definition.</li> | ||
<li>Precompiled procedures can contain the User Language INCLUDE statement. The included procedures must be from a subsystem file. Any code inserted as a result of an INCLUDE statement is subject to all the restrictions for precompiled procedures. </li> | <li>Precompiled procedures can contain the User Language INCLUDE statement. The included procedures must be from a subsystem file. Any code inserted as a result of an INCLUDE statement is subject to all the restrictions for precompiled procedures. </li> | ||
<li>If a precompiled procedure issues the INCLUDE command to compile and run a User Language request, the INCLUDE command is saved, not the compilation of the request that was included.</li> | <li>If a precompiled procedure issues the INCLUDE command to compile and run a User Language request, the INCLUDE command is saved, not the compilation of the request that was included.</li> | ||
<li>Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.</li> | <li>Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.</li> | ||
<li>Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.</li> | <li>Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.</li> | ||
<li>Dummy string substitution does not take place when saving commands that contain dummy strings. Instead, when the saved commands are loaded and executed, the current value of the dummy string is used. For example, if you include the following command in a precompiled procedure, whatever is currently in the global COMMAND is executed. | <li>Dummy string substitution does not take place when saving commands that contain dummy strings. Instead, when the saved commands are loaded and executed, the current value of the dummy string is used. For example, if you include the following command in a precompiled procedure, whatever is currently in the global COMMAND is executed. | ||
<p class="code">?%COMMAND | <p class="code">?%COMMAND | ||
</p></li> | </p></li> | ||
<li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | <li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | ||
<li>Procedures in UNLOCKed members of a PROCFILE GROUP are not precompiled. | <li>Procedures in UNLOCKed members of a PROCFILE GROUP are not precompiled. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>Precompiled requests can refer to temporary or ad hoc groups as long as the files making up the group are specified in the subsystem definition. A temporary group of the same name must have the same composition characteristics for all loading users, as described below. If this condition is not met, <var class="product">Model 204</var> sets the error global variable to GRP-TEMP MISMATCH (see [[#Error global variable|Error global variable]]).</p> | ===Restrictions for temporary and ad hoc groups in precompiled procedures=== | ||
<p> | |||
Precompiled requests can refer to temporary or ad hoc groups as long as the files making up the group are specified in the subsystem definition. A temporary group of the same name must have the same composition characteristics for all loading users, as described below. If this condition is not met, <var class="product">Model 204</var> sets the error global variable to GRP-TEMP MISMATCH (see [[#Error global variable|Error global variable]]).</p> | |||
<ul> | <ul> | ||
<li>The temporary group for all loading users must be the same type. <var class="product">Model 204</var> assigns a type, based on the following file conditions: | <li>The temporary group for all loading users must be the same type. <var class="product">Model 204</var> assigns a type, based on the following file conditions: | ||
<ul> | <ul> | ||
<li>Some files have record security.</li> | <li>Some files have record security.</li> | ||
<li>All files are sorted or all are hashed.</li> | <li>All files are sorted or all are hashed.</li> | ||
<li>The sort or hash key has the same name in all files. </li> | <li>The sort or hash key has the same name in all files. </li> | ||
</ul> | </ul></li> | ||
<li>Fields of the same name in the temporary group must be of the same type. Each field referenced in a temporary group each time a precompiled procedure is invoked must be found in a file. If this condition is not met, <var class="product">Model 204</var> sets the error global variable to GRP-TEMP FIELD (see [[#Error global variable|Error global variable]]). | |||
<p>Field definition attributes can change for fields in temporary groups between compile and loading time. The following changes are allowed:</p | <li>Fields of the same name in the temporary group must be of the same type. Each field referenced in a temporary group each time a precompiled procedure is invoked must be found in a file. If this condition is not met, <var class="product">Model 204</var> sets the error global variable to GRP-TEMP FIELD (see [[#Error global variable|Error global variable]]). | ||
<p> | |||
Field definition attributes can change for fields in temporary groups between compile and loading time. The following changes are allowed:</p> | |||
<ul> | <ul> | ||
<li>If the field is NON-CODED in any file at compile time, it can be CODED in all files at loading time.</li> | <li>If the field is NON-CODED in any file at compile time, it can be CODED in all files at loading time.</li> | ||
<li>If the field is BINARY or FLOAT in any file at compile time, it can be STRING in all files at loading time.</li> | <li>If the field is BINARY or FLOAT in any file at compile time, it can be STRING in all files at loading time.</li> | ||
<li>If the field is non-NUMERIC RANGE in any file at compile time, the field can be NUMERIC RANGE in all of the files at loading time.</li> | <li>If the field is non-NUMERIC RANGE in any file at compile time, the field can be NUMERIC RANGE in all of the files at loading time.</li> | ||
</ul></li> | |||
</ul> | </ul> | ||
===Recompiling precompiled procedures=== | |||
<p> | |||
<p>When designing applications which use precompiled procedures and temporary groups, be aware that temporary groups can cause <var class="product">Model 204</var> to recompile precompiled procedures under certain conditions. </p> | When designing applications which use precompiled procedures and temporary groups, be aware that temporary groups can cause <var class="product">Model 204</var> to recompile precompiled procedures under certain conditions. </p> | ||
<p>Precompiled procedures are recompiled when the request references a temporary group and the:</p> | <p> | ||
Precompiled procedures are recompiled when the request references a temporary group and the:</p> | |||
<ul> | <ul> | ||
<li>Compiling user's temporary group consists of files which are smaller than one or more of the files in the loading user's temporary group of the same name.</li> | <li>Compiling user's temporary group consists of files which are smaller than one or more of the files in the loading user's temporary group of the same name.</li> | ||
<li>Compiling user's temporary group has fewer files than the loading user's temporary group of the same name. </li> | <li>Compiling user's temporary group has fewer files than the loading user's temporary group of the same name. </li> | ||
<li>Update and retrieve privileges do not match those of the compiling user's temporary group (of the same name). | <li>Update and retrieve privileges do not match those of the compiling user's temporary group (of the same name). | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>If one user's temporary group contains one large file, and another user's temporary group contains a number of smaller files, it is possible that a precompiled procedure is recompiled every time it is invoked. To prevent constant recompiling when files are of different sizes, compile temporary groups originally with the largest files and the greatest number files you expect to be included in the temporary group.</p> | <p> | ||
<p>If, despite precautions, <var class="product">Model 204</var> must discard and recompile a precompiled procedure, the loading user must have exclusive access to that procedure | If one user's temporary group contains one large file, and another user's temporary group contains a number of smaller files, it is possible that a precompiled procedure is recompiled every time it is invoked. To prevent constant recompiling when files are of different sizes, compile temporary groups originally with the largest files and the greatest number files you expect to be included in the temporary group.</p> | ||
<p> | |||
<p>When a non-precompiled procedure that references remote files is invoked, one or more remote nodes participate in the compilation and evaluation. When a precompiled procedure is invoked, <var class="product">Model 204</var> loads the procedure on each of the nodes that participated in the original compilation.</p> | If, despite precautions, <var class="product">Model 204</var> must discard and recompile a precompiled procedure, the loading user must have exclusive access to that procedure: no other user can be executing the procedure within the same subsystem. If another user is executing the procedure, the loading user recompiles a private copy of the procedure. <var class="product">Model 204</var> discards the private copy when execution has completed. </p> | ||
<p>When a subsystem member becomes unavailable during evaluation, the appropriate ON unit is activated. </p> | |||
<p>Errors which occur while loading a remote procedure produce error messages which have the prefix RMT in the global error variable.</p> | ===Procedure compilation and Parallel Query Option/204=== | ||
<p> | |||
<p>As part of the compilation process, a list of remote nodes referenced in the request is generated with the compiled code. When compilation is complete, the compilation is saved along with the list of nodes. Each remote node referenced in the request is sent a signal to save the compilation. </p> | When a non-precompiled procedure that references remote files is invoked, one or more remote nodes participate in the compilation and evaluation. When a precompiled procedure is invoked, <var class="product">Model 204</var> loads the procedure on each of the nodes that participated in the original compilation.</p> | ||
<p>If for any reason a compilation cannot be saved by a server node, the entire save operation fails.</p> | <p> | ||
When a subsystem member becomes unavailable during evaluation, the appropriate ON unit is activated. </p> | |||
<p>At the client node, the saved remote node reference list is checked to see which nodes are loading the request. When the request is loaded on the client, a signal is transmitted to each referenced server node to load the compilation. </p> | <p> | ||
Errors which occur while loading a remote procedure produce error messages which have the prefix RMT in the global error variable.</p> | |||
<p>A temporary group can be changed so that a node is new (not previously referenced) or missing (referenced but no longer available). [[#New and missing nodes|Temporary groups with new and missing nodes]] shows how new and missing nodes affect recompilations and saves. </p> | |||
====Saving compilations==== | |||
<p> | |||
As part of the compilation process, a list of remote nodes referenced in the request is generated with the compiled code. When compilation is complete, the compilation is saved along with the list of nodes. Each remote node referenced in the request is sent a signal to save the compilation. </p> | |||
<p> | |||
If for any reason a compilation cannot be saved by a server node, the entire save operation fails.</p> | |||
====Loading saved compilations==== | |||
<p> | |||
At the client node, the saved remote node reference list is checked to see which nodes are loading the request. When the request is loaded on the client, a signal is transmitted to each referenced server node to load the compilation. </p> | |||
====New and missing nodes==== | |||
<p> | |||
A temporary group can be changed so that a node is <b>new</b> (not previously referenced) or <b>missing</b> (referenced but no longer available). [[#New and missing nodes|Temporary groups with new and missing nodes]] shows how new and missing nodes affect recompilations and saves. </p> | |||
<table> | <table> | ||
<caption>Temporary groups with new and missing nodes</caption> | <caption>Temporary groups with new and missing nodes</caption> | ||
<tr class="head"> | <tr class="head"> | ||
<th> </th> | <th> </th> | ||
<th>If there are | <th>If there are | ||
missing nodes...</th> | missing nodes...</th> | ||
<th>If there are no | <th>If there are no | ||
missing nodes....</th> | missing nodes....</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>And there are new nodes...</td> | <td>And there are new nodes...</td> | ||
Line 404: | Line 520: | ||
<td>Recompile and save again</td> | <td>Recompile and save again</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>And there are no new nodes...</td> | <td>And there are no new nodes...</td> | ||
Line 409: | Line 526: | ||
<td>Just load and evaluate</td> | <td>Just load and evaluate</td> | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>Saved requests are always recompiled if a new node is introduced into a temporary group. Recompilation can cause a noticeable delay in response time.</p> | ====Recompiling saved requests==== | ||
<p>In addition, the following changes in the composition of a subgroup also force recompilation of a request. A subgroup is the group of files at a server node referenced as a part of a group.</p> | <p> | ||
<p><var class="product">Model 204</var> recompiles saved requests when:</p> | Saved requests are always recompiled if a new node is introduced into a temporary group. Recompilation can cause a noticeable delay in response time.</p> | ||
<p> | |||
In addition, the following changes in the composition of a subgroup also force recompilation of a request. A subgroup is the group of files at a server node referenced as a part of a group.</p> | |||
<p> | |||
<var class="product">Model 204</var> recompiles saved requests when:</p> | |||
<ul> | <ul> | ||
<li>The number of files in the subgroup has increased (for example, if a user's request includes a file that was unavailable to the previous user)</li> | <li>The number of files in the subgroup has increased (for example, if a user's request includes a file that was unavailable to the previous user)</li> | ||
<li>The maximum number of segments in a subgroup has increased | <li>The maximum number of segments in a subgroup has increased | ||
</li> | </li> | ||
</ul> | </ul> | ||
==Subsystem procedures== | |||
<p>Subsystem development involves writing the collection of procedures that make up a subsystem. Subsystem procedures can be categorized as one of four types: </p> | ===Types of subsystem procedures=== | ||
<p> | |||
Subsystem development involves writing the collection of procedures that make up a subsystem. Subsystem procedures can be categorized as one of four types: </p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 429: | Line 552: | ||
<th>Performs...</th> | <th>Performs...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>Initialization</var> </td> | <td><var>Initialization</var> </td> | ||
<td>Specified operations each time the subsystem is initialized.</td> | <td>Specified operations each time the subsystem is initialized.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>Login</var> </td> | <td><var>Login</var> </td> | ||
<td>As the entry point for each user of the subsystem.</td> | <td>As the entry point for each user of the subsystem.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>Main processing</var> </td> | <td><var>Main processing</var> </td> | ||
<td>Specific tasks of the subsystem.</td> | <td>Specific tasks of the subsystem.</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>Error</var> </td> | <td><var>Error</var> </td> | ||
Line 446: | Line 573: | ||
</tr> | </tr> | ||
</table> | </table> | ||
===Guidelines and restrictions=== | |||
<ul> | <ul> | ||
<li>Procedures should be small and modular.</li> | <li>Procedures should be small and modular.</li> | ||
<li>Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.</li> | <li>Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.</li> | ||
<li>Non-subsystem files can be opened and referenced only by non precompiled procedures.</li> | <li>Non-subsystem files can be opened and referenced only by non precompiled procedures.</li> | ||
<li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | <li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | ||
<li>A subsystem procedure cannot issue the CREATE command for a subsystem file.</li> | <li>A subsystem procedure cannot issue the CREATE command for a subsystem file.</li> | ||
<li>LXTBL and LFTBL cannot be reset from within a subsystem procedure.</li> | <li>LXTBL and LFTBL cannot be reset from within a subsystem procedure.</li> | ||
<li>All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed. The default action for each type of message is listed in | <li>All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed. The default action for each type of message is listed in [[M204.1076]]. | ||
<p>If you do not wish the default action to be executed, statements to handle a situation that would invoke the message should be added to the procedure. </p> | <p> | ||
If you do not wish the default action to be executed, statements to handle a situation that would invoke the message should be added to the procedure. </p> | |||
</li> | </li> | ||
</ul> | </ul> | ||
===Initialization procedure=== | |||
<p>The initialization procedure stores instructions for tasks you need to perform each time the subsystem is initialized. An example of such a task is the initialization of a particular work file. </p> | <p> | ||
<p>The initialization procedure is optional. If a subsystem uses an initialization procedure, the procedure name must be specified in the subsystem definition.</p> | The initialization procedure stores instructions for tasks you need to perform each time the subsystem is initialized. An example of such a task is the initialization of a particular work file. </p> | ||
<p> | |||
<p>The login procedure performs the start up for each user of an application. Every time a user invokes the subsystem, <var class="product">Model 204</var> automatically includes the subsystem login procedure. </p> | The initialization procedure is optional. If a subsystem uses an initialization procedure, the procedure name must be specified in the subsystem definition.</p> | ||
<p>The login procedure name must be specified in the subsystem definition. </p> | |||
<p>Typically, the login procedure is used to store current server table sizes in the global variable table for later reference, issue UTABLE commands to set compiler table sizes for the subsystem, and set the communication global variable to the name of the procedure that displays an initial menu. </p> | ===Login procedure=== | ||
<p> | |||
The login procedure performs the start up for each user of an application. Every time a user invokes the subsystem, <var class="product">Model 204</var> automatically includes the subsystem login procedure. </p> | |||
<p> | |||
The login procedure name must be specified in the subsystem definition. </p> | |||
<p> | |||
Typically, the login procedure is used to store current server table sizes in the global variable table for later reference, issue UTABLE commands to set compiler table sizes for the subsystem, and set the communication global variable to the name of the procedure that displays an initial menu. </p> | |||
<b>Example</b> | <b>Example</b> | ||
<p>Here is a sample login procedure:</p> | <p> | ||
Here is a sample login procedure:</p> | |||
<p class="code">CLEARG | <p class="code">CLEARG | ||
BEGIN | BEGIN | ||
Line 488: | Line 624: | ||
UTABLE LNTBL=450,LQTBL=2300,LVTBL=600,LSTBL=3300 | UTABLE LNTBL=450,LQTBL=2300,LVTBL=600,LSTBL=3300 | ||
UTABLE LFSCB=5000 | UTABLE LFSCB=5000 | ||
RESET LECHO 0 | RESET LECHO 0 | ||
</p> | </p> | ||
<p>Main processing procedures perform the specific tasks of the subsystem. There can be as few or as many main processing procedures as necessary for the subsystem to perform its tasks. Main processing procedures are not specified in the subsystem definition. However, each procedure must follow the procedure naming conventions and subsystem coding rules discussed | ===Main processing procedures=== | ||
<p> | |||
<p>Here is a sample procedure:</p> | Main processing procedures perform the specific tasks of the subsystem. There can be as few or as many main processing procedures as necessary for the subsystem to perform its tasks. Main processing procedures are not specified in the subsystem definition. However, each procedure must follow the procedure naming conventions and subsystem coding rules discussed on this page. </p> | ||
====Example==== | |||
<p> | |||
Here is a sample procedure:</p> | |||
<p class="code">BEGIN | <p class="code">BEGIN | ||
MENU MAINMENU | MENU MAINMENU | ||
Line 515: | Line 655: | ||
END IF | END IF | ||
END REPEAT | END REPEAT | ||
CHK.GTAB: IF $SETG('NEXT',%NEXT)THEN | CHK.GTAB: IF $SETG('NEXT',%NEXT) THEN | ||
AUDIT 'GLOBAL TABLE FULL - "NEXT"' | AUDIT 'GLOBAL TABLE FULL - "NEXT"' | ||
END IF | END IF | ||
END | END | ||
</p> | </p> | ||
<p>An error procedure, which is optional, performs error handling. This procedure is invoked when a condition occurs that cannot be trapped by the executing procedure (for example, a compiler error or an attention with no ON ATTENTION unit coded). An error procedure tests for different error conditions and determines the next procedure to execute, based on the error code value stored in the error global variable. Terminal I/O in a subsystem error procedure following a BUMP or inactive thread timeout results in cancellation of the procedure. </p> | ===Error procedure=== | ||
<p> | |||
<p>The following error procedure assumes that the error global variable name is ERRCLASS, the communication global variable name is NEXT, and the exit value of the communication global variable is EXIT.</p> | An error procedure, which is optional, performs error handling. This procedure is invoked when a condition occurs that cannot be trapped by the executing procedure (for example, a compiler error or an attention with no ON ATTENTION unit coded). An error procedure tests for different error conditions and determines the next procedure to execute, based on the error code value stored in the error global variable. Terminal I/O in a subsystem error procedure following a BUMP or inactive thread timeout results in cancellation of the procedure. </p> | ||
====Example==== | |||
<p> | |||
The following error procedure assumes that the error global variable name is ERRCLASS, the communication global variable name is NEXT, and the exit value of the communication global variable is EXIT.</p> | |||
<p class="code">PROCEDURE SYS-ERROR | <p class="code">PROCEDURE SYS-ERROR | ||
BEGIN | BEGIN | ||
Line 554: | Line 698: | ||
%NEXT = 'EXIT' | %NEXT = 'EXIT' | ||
<b></b>* | <b></b>* | ||
<b></b>* SOME UNACCOUNTABLE ERROR HAS OCCURRED, SET EXIT | <b></b>* SOME UNACCOUNTABLE ERROR HAS OCCURRED, SET EXIT | ||
<b></b>* ROUTINE, AND EXIT WITHOUT DOING ANY TERMINAL I/O. | <b></b>* ROUTINE, AND EXIT WITHOUT DOING ANY TERMINAL I/O. | ||
<b></b>* | <b></b>* | ||
Line 565: | Line 709: | ||
<b></b>* SET COMMUNICATIONS VARIABLE TO EXIT VALUE | <b></b>* SET COMMUNICATIONS VARIABLE TO EXIT VALUE | ||
<b></b>* | <b></b>* | ||
COMM.VAR: IF $SETG('NEXT',%NEXT) THEN PRINT 'GTBL FULL' | COMM.VAR: IF $SETG('NEXT',%NEXT) THEN | ||
AUDIT 'GTBL full in SYS-ERROR trying to set NEXT to ' WITH %NEXT | |||
PRINT 'GTBL FULL' | |||
END IF | END IF | ||
END.REQUEST: | END.REQUEST: * | ||
END | END | ||
END PROCEDURE | |||
</p> | </p> | ||
<p>During subsystem definition, various options are specified for a subsystem. Security options determine subsystem command and file and group privileges assigned to a user. </p> | ==Security options== | ||
<p>You can also specify system operation options during subsystem definition. System operation options are discussed in the | <p> | ||
During subsystem definition, various options are specified for a subsystem. Security options determine subsystem command and file and group privileges assigned to a user. </p> | |||
<p>The status of the subsystem affects the type of subsystem security that is implemented. The subsystem can have one of three status settings: | <p> | ||
You can also specify system operation options during subsystem definition. System operation options are discussed in the [[#Operating options|Operating options]] section. | |||
For a detailed discussion of subsystem definition options, refer to [[System requirements for Application Subsystems]]. </p> | |||
===Status of subsystem=== | |||
<p> | |||
The status of the subsystem affects the type of subsystem security that is implemented. The subsystem can have one of three status settings: </p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 580: | Line 733: | ||
<th>Allows access to...</th> | <th>Allows access to...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Public </td> | <td>Public </td> | ||
<td>All users. All users who enter a public subsystem are assigned to the single subsystem user class and have the same set of privileges. </td> | <td>All users. All users who enter a public subsystem are assigned to the single subsystem user class and have the same set of privileges. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Semipublic </td> | <td>Semipublic </td> | ||
<td>All users but permits different privileges to be assigned for each user. In a semipublic subsystem, one subsystem user class can be defined as the default class for all users not specifically assigned to another subsystem user class. | <td>All users but permits different privileges to be assigned for each user. In a semipublic subsystem, one subsystem user class can be defined as the default class for all users not specifically assigned to another subsystem user class. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Private </td> | <td>Private </td> | ||
Line 593: | Line 749: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>The set of privileges assigned to a user is based on the user's subsystem user class or SCLASS. The SCLASS is used by <var class="product">Model 204</var> to determine the privileges assigned for each file and group in the subsystem when files are opened for the user. File and group privileges must be specified in the subsystem definition because <var class="product">Model 204</var> bypasses OPENCTL parameter settings and file passwords when opening subsystem files and groups for each user. Whenever the user invokes the subsystem, he/she is assigned the file and group privileges of that subsystem user class. </p> | ===User class=== | ||
<p>The SCLASS also determines whether or not the user can issue any of the subsystem control commands listed below. If <var class="product">Model 204</var> discovers that the user does not have the correct privileges to issue a command, an error message is displayed.</p> | <p> | ||
The set of privileges assigned to a user is based on the user's subsystem user class or SCLASS. The SCLASS is used by <var class="product">Model 204</var> to determine the privileges assigned for each file and group in the subsystem when files are opened for the user. File and group privileges must be specified in the subsystem definition because <var class="product">Model 204</var> bypasses <var>OPENCTL</var> parameter settings and file passwords when opening subsystem files and groups for each user. Whenever the user invokes the subsystem, he/she is assigned the file and group privileges of that subsystem user class. </p> | |||
<p> | |||
The SCLASS also determines whether or not the user can issue any of the subsystem control commands listed below. If <var class="product">Model 204</var> discovers that the user does not have the correct privileges to issue a command, an error message is displayed.</p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
<th>Subsystem | <th>Subsystem control commands </th> | ||
control commands </th> | <th>Directs Model 204 to...</th> | ||
<th> | |||
Directs | |||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>DEBUG SUBSYSTEM</var> </td> | <td><var>DEBUG SUBSYSTEM</var> </td> | ||
<td | <td>Establish a test environment for a multiuser version of the <var>TEST</var> command extension. The subsystem does not have to be stopped to issue the <var>DEBUG</var> command. | ||
<p> | |||
<p>When a user enters a subsystem in TEST or DEBUG mode, the user's MSGCTL parameter setting is not changed. All error and informational messages that are not suppressed by the user's MSGCTL setting are displayed on the user's terminal. | When a user enters a subsystem in <var>TEST</var> or <var>DEBUG</var> mode, the user's MSGCTL parameter setting is not changed. All error and informational messages that are not suppressed by the user's <var>MSGCTL</var> setting are displayed on the user's terminal. </p> | ||
</td> | </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>START SUBSYSTEM</var> </td> | <td><var>START SUBSYSTEM</var> </td> | ||
<td>Activate the subsystem and make it available for use. If the subsystem is inactive when the START command is issued, <var class="product">Model 204</var> opens all the subsystem files and includes the subsystem initialization procedure. | <td>Activate the subsystem and make it available for use. If the subsystem is inactive when the <var>START</var> command is issued, <var class="product">Model 204</var> opens all the subsystem files and includes the subsystem initialization procedure. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>STOP SUBSYSTEM</var> </td> | <td><var>STOP SUBSYSTEM</var> </td> | ||
<td>Stop the subsystem and make it unavailable for use. Once a subsystem is stopped and all users have exited, then all locking and storage resources held by the subsystem are released and all the subsystem files and groups are closed. | <td>Stop the subsystem and make it unavailable for use. Once a subsystem is stopped and all users have exited, then all locking and storage resources held by the subsystem are released and all the subsystem files and groups are closed. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td><var>TEST</var> </td> | <td><var>TEST</var> </td> | ||
<td>Establish a single user test environment. The TEST command is extended to TEST DEBUG SUBSYSTEM. The subsystem must be stopped to enter TEST mode.</td> | <td>Establish a single user test environment. The <var>TEST</var> command is extended to <var>TEST DEBUG SUBSYSTEM</var>. The subsystem must be stopped to enter <var>TEST</var> mode.</td></tr> | ||
</tr> | |||
</table> | </table> | ||
<p class="note"><b>Note:</b> Several aspects of START SUBSYSTEM and STOP SUBSYSTEM processing are unique to distributed applications. For a discussion, see | |||
<p class="note"><b>Note:</b> Several aspects of <var>START SUBSYSTEM</var> and <var>STOP SUBSYSTEM</var> processing are unique to distributed applications. For a discussion, see [[PQO: Scattered APSY subsystems#Subsystem command processing|Subsystem command processing]].</p> | |||
<p>The application subsystem traps security violations that occur while a user is running in a subsystem. File read and update security violations, procedure security violations, and field level security violations are interpreted as compilation or evaluation errors in the error global variable. The audit trail messages produced when the error occurred can be examined in order to identify a compilation or evaluation error as a security violation. </p> | |||
===Processing of security violations=== | |||
<p>In the following situation, <var class="product">Model 204</var> saves User 1's compilation:</p> | <p> | ||
The application subsystem traps security violations that occur while a user is running in a subsystem. File read and update security violations, procedure security violations, and field level security violations are interpreted as compilation or evaluation errors in the error global variable. The audit trail messages produced when the error occurred can be examined in order to identify a compilation or evaluation error as a security violation. </p> | |||
===Compiling procedures with a different SCLASS=== | |||
<p> | |||
In the following situation, <var class="product">Model 204</var> saves User 1's compilation:</p> | |||
<ol> | <ol> | ||
<li>There are multiple SCLASSes for a subsystem.</li> | <li>There are multiple SCLASSes for a subsystem.</li> | ||
Line 634: | Line 799: | ||
<li>User 2's global variables contain different information from User 1's so User 2 tries to open different files or groups than User 1. </li> | <li>User 2's global variables contain different information from User 1's so User 2 tries to open different files or groups than User 1. </li> | ||
</ol> | </ol> | ||
<p>However, User 2's compilation is not saved: User 2 receives an error message:</p> | <p> | ||
<p class="code">M204.0468: COMPILATION NOT SAVED - reason | However, User 2's compilation is not saved: User 2 receives an error message:</p> | ||
<p class="code">M204.0468: COMPILATION NOT SAVED - <i>reason</i> | |||
</p> | </p> | ||
==Operating options== | |||
<p>Operating options affect certain aspects of the overall behavior of a subsystem. Operating options are distinct from security options, which are discussed in [[#Security options|Security options]]. Subsystem options are also discussed in | <p> | ||
<p>The following table lists the operating options and what they determine.</p> | Operating options affect certain aspects of the overall behavior of a subsystem. Operating options are distinct from security options, which are discussed in [[#Security options|Security options]]. | ||
Subsystem options are also discussed in [[System requirements for Application Subsystems]]. </p> | |||
<p> | |||
The following table lists the operating options and what they determine.</p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 646: | Line 815: | ||
<th>Determines whether...</th> | <th>Determines whether...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Automatic start </td> | <td>Automatic start </td> | ||
<td>Subsystem automatically starts for the first user entering the subsystem. </td> | <td>Subsystem automatically starts for the first user entering the subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Locking files and groups for subsystem use </td> | <td>Locking files and groups for subsystem use </td> | ||
<td>Users from outside the subsystem can open and update subsystem files while the subsystem is active. </td> | <td>Users from outside the subsystem can open and update subsystem files while the subsystem is active. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Automatic login </td> | <td>Automatic login </td> | ||
<td>Users are automatically logged into <var class="product">Model 204</var> upon entering a subsystem. </td> | <td>Users are automatically logged into <var class="product">Model 204</var> upon entering a subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Automatic logout </td> | <td>Automatic logout </td> | ||
<td>Users are automatically logged out of <var class="product">Model 204</var> upon exiting a subsystem. </td> | <td>Users are automatically logged out of <var class="product">Model 204</var> upon exiting a subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Automatic COMMIT </td> | <td>Automatic COMMIT </td> | ||
<td>Any outstanding updates are committed automatically whenever a subsystem procedure ends and transfers control using the communications global variable. </td> | <td>Any outstanding updates are committed automatically whenever a subsystem procedure ends and transfers control using the communications global variable. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Message displays </td> | <td>Message displays </td> | ||
<td>Disconnect, informational, and error messages are displayed for subsystem users. </td> | <td>Disconnect, informational, and error messages are displayed for subsystem users. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>File usage </td> | <td>File usage </td> | ||
Line 675: | Line 851: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>If the automatic start option is selected, <var class="product">Model 204</var> invokes subsystem initialization when the first user attempts to enter the subsystem. The subsystem can be used without a privileged user first issuing the START SUBSYSTEM command.</p> | ===Automatic start=== | ||
<p>If the automatic start option is not selected, subsystem initialization occurs only when the START SUBSYSTEM command is issued. The subsystem is then available for use. </p> | <p> | ||
If the automatic start option is selected, <var class="product">Model 204</var> invokes subsystem initialization when the first user attempts to enter the subsystem. The subsystem can be used without a privileged user first issuing the START SUBSYSTEM command.</p> | |||
<p>If the locking files and groups option is selected, <var class="product">Model 204</var> prevents users that are not running in the subsystem from opening any of the subsystem files or groups while the subsystem is active. </p> | <p> | ||
<p>If the locking files and groups option is not selected, users from outside the subsystem can retrieve, modify, or delete records in a subsystem file while the subsystem is active. </p> | If the automatic start option is not selected, subsystem initialization occurs only when the START SUBSYSTEM command is issued. The subsystem is then available for use. </p> | ||
<p>If the automatic login option is selected, <var class="product">Model 204</var> logs on the user when the user enters a subsystem. The user is logged in using the subsystem name as the <var class="product">Model 204</var> user ID. If the user already has logged into <var class="product">Model 204</var> before entering the subsystem, <var class="product">Model 204</var> first closes all the user's files and logs out the user. </p> | ===Locking files and groups for subsystem use=== | ||
<p>The LOGOUT operations that occur as a result of Automatic Login (both at subsystem Login and Disconnect) ignore the SYSOPT=8 (DISCONNECT on LOGOUT) option.</p> | <p> | ||
<p>If the login option is not selected, the user's <var class="product">Model 204</var> user ID is used during subsystem processing. </p> | If the locking files and groups option is selected, <var class="product">Model 204</var> prevents users that are not running in the subsystem from opening any of the subsystem files or groups while the subsystem is active. </p> | ||
<p> | |||
<p>If the automatic logout option is selected, the user is logged out of <var class="product">Model 204</var> upon exiting the subsystem. This option is particularly useful when combined with the automatic disconnect feature of <var class="product">Model 204</var>. </p> | If the locking files and groups option is not selected, users from outside the subsystem can retrieve, modify, or delete records in a subsystem file while the subsystem is active. </p> | ||
<p>The START SUBSYSTEM command ignores the SYSOPT=8 option for the Automatic Logout subsystem.</p> | |||
<p>If the automatic logout option is not selected, <var class="product">Model 204</var> logs the user out of the subsystem in one of three ways:</p> | ===Automatic login=== | ||
<p> | |||
If the automatic login option is selected, <var class="product">Model 204</var> logs on the user when the user enters a subsystem. The user is logged in using the subsystem name as the <var class="product">Model 204</var> user ID. If the user already has logged into <var class="product">Model 204</var> before entering the subsystem, <var class="product">Model 204</var> first closes all the user's files and logs out the user. </p> | |||
<p> | |||
The LOGOUT operations that occur as a result of Automatic Login (both at subsystem Login and Disconnect) ignore the SYSOPT=8 (DISCONNECT on LOGOUT) option.</p> | |||
<p> | |||
If the login option is not selected, the user's <var class="product">Model 204</var> user ID is used during subsystem processing. </p> | |||
===Automatic logout=== | |||
<p> | |||
If the automatic logout option is selected, the user is logged out of <var class="product">Model 204</var> upon exiting the subsystem. This option is particularly useful when combined with the automatic disconnect feature of <var class="product">Model 204</var>. </p> | |||
<p> | |||
The START SUBSYSTEM command ignores the SYSOPT=8 option for the Automatic Logout subsystem.</p> | |||
<p> | |||
If the automatic logout option is not selected, <var class="product">Model 204</var> logs the user out of the subsystem in one of three ways:</p> | |||
<ul> | <ul> | ||
<li>If the user was previously logged into <var class="product">Model 204</var>, <var class="product">Model 204</var> restores the user's original user ID and returns the user to the <var class="product">Model 204</var> command environment.</li> | <li>If the user was previously logged into <var class="product">Model 204</var>, <var class="product">Model 204</var> restores the user's original user ID and returns the user to the <var class="product">Model 204</var> command environment.</li> | ||
<li>If the user was not previously logged into <var class="product">Model 204</var>, the user is logged out of <var class="product">Model 204</var>.</li> | |||
<li>The SYSOPT=8 option causes the user to be disconnected from <var class="product">Model 204</var>. | |||
</li> | </li> | ||
< | </ul> | ||
===Automatic COMMIT=== | |||
<p> | |||
If the automatic COMMIT option is selected, <var class="product">Model 204</var> automatically issues a COMMIT statement for any outstanding updates whenever a subsystem procedure terminates and transfers control using the communication global variable. If the COMMIT option is not selected, the application must issue the COMMIT statement to commit any pending updates. </p> | |||
===Commit exits=== | |||
<p class="note"><b>Note:</b> This feature is available as of Model 204 release 7.8. It is licensed and purchased separately from Model 204.</p> | |||
A commit exit enables you to set up SOUL code to run at commit time, as in: "on commit run <var class="term">xxx</var>". | |||
When the user executes a commit (or an implied commit), the APSY specified by <var>COMMITX</var> is driven on a transactional daemon. | |||
The APSY follows standard APSY rules. The commit exit is only driven once; that is, subsequent commits do not call the APSY. The commit exit is only driven for TBO transactions. | |||
A commit/backout coded inside the commit exit commits/backs out the active transaction. Any new transaction within the exit causes a new update unit to begin. | |||
====COMMITX parameter==== | |||
The commit exit runs within the APSY defined by the <var>COMMITX</var> parameter and uses normal APSY processing. | |||
The new parameter <var>COMMITX</var> is settable from User 0's parameter line or by the system manager. It can be reset at any time by the system manager. | |||
Setting/Resetting the parameter sends a DYRWT message to the issuer and requires a Yes or No response (unless set/reset by user0). | |||
If <var>COMMITX</var> is specified, all APSY subsystems participate by default but any can be exempted. | |||
====Activating the commit exit APSY==== | |||
<ul> | |||
<li>To activate the commit exit APSY, issue: | |||
<p class="code">Reset COMMITX <var class="term">apsyname</var></p> | |||
where <var class="term">apsyname</var> is the APSY where you are running the commit exit. | |||
<p>Enter <code>Yes</code> at the confirmation prompt.</p></li> | |||
<li>To exempt any APSY subsystem: | |||
<ol> | |||
<li>Pull up the SUBSYSMGMT <var>Operational Parameters</var> screen for that subsystem.</li> | |||
<li>At the 'Subsystem supports commit exit' item, enter <code>N</code>.</li> | |||
</ol> | |||
</li> | </li> | ||
<li> | |||
<li>To deactivate the commit exit APSY, issue: | |||
<p class="code">Reset COMMITX</p> | |||
<p>Enter <code>Yes</code> at the confirmation prompt.</p> | |||
</li> | </li> | ||
</ul> | </ul> | ||
==== | |||
<p>If the | ====Examples==== | ||
<p><var class="product">Model 204</var> provides these message display options for subsystem users: </p> | The following are examples of login exits which print all changed records. | ||
=====Example 1===== | |||
<p class="code">b | |||
%d object xmldoc auto new | |||
%rec object xmldoc auto new | |||
%d:loadchangedrecords | |||
%f string len 8 | |||
%r float | |||
%c float initial(1) | |||
repeat %d:selectcount('//Record') times | |||
%f = %d:value('//Record[' %c ']/@file') | |||
%r = %d:value('//Record[' %c ']/@number') | |||
%c = %c + 1 | |||
%rec:loadfromrecord(FILE=%f,RECORDNUMBER=%r) | |||
%rec:print | |||
%rec = new | |||
end repeat | |||
if $SETG('NEXT','EXIT') then | |||
audit 'gtbl full' | |||
end if | |||
end </p> | |||
=====Example 2===== | |||
<p class="code">b | |||
%d object xmldoc auto new | |||
%d:loadchangedrecords(fields=true) | |||
%d:print | |||
if $SETG('NEXT','EXIT') then | |||
audit 'gtbl full' | |||
end if | |||
end </p> | |||
=====Example 3===== | |||
<p class="code">b | |||
%d object xmldoc auto new | |||
%recs object xmldoc auto new | |||
%n object xmlnode | |||
%d:loadchangedrecords | |||
%f string len 8 | |||
%r float | |||
%c float initial(1) | |||
%n = %recs:AddElement('ChangedRecords') | |||
repeat %d:selectcount('//Record') times | |||
%f = %d:value('//Record[' %c ']/@file') | |||
%r = %d:value('//Record[' %c ']/@number') | |||
%c = %c + 1 | |||
%n:loadfromrecord(FILE=%f,RECORDNUMBER=%r,HEADER=TRUE) | |||
end repeat | |||
%recs:print | |||
if $SETG('NEXT','EXIT') then | |||
audit 'gtbl full' | |||
end if | |||
end </p> | |||
There are new parameters for several of the methods (as demonstrated above): | |||
<p class="code">LoadChangedRecords: | |||
Fields=boolean (default=false)</p> | |||
If true, each individual changed record is loaded into the XMLDOC similar to LoadFromRecord. | |||
<p class="code">LoadFromRecord: | |||
File=name | |||
RecordNumber=number </p> | |||
LoadFrom Record must normally be issued within a FOR record context. However, if both of these name required parameters are specified, the LoadFromRecord statement need not be within a FOR record context. | |||
If either of these name required parameters is specified from within a FOR record context, an error message will be issued: <code>ERROR 1081: %C inside record loop: Recordnumber/File parameters not allowed</code> | |||
<p class="code">LoadFromRecord: | |||
Header=Boolean (default=false)</p> | |||
If true, the header line of the method will be included for each item. This may be useful when LoadFromRecord is issued in order to load an XMLNODE. | |||
The header will separate each record and designate the file and record number. | |||
====Error handling==== | |||
=====Current behavior without commit exits===== | |||
Without commit exits, an APSY does not commit automatically unless AUTOCOMMIT=Y is specified in the APSY definition. | |||
<ul> | |||
<li>If a transactional daemon is created: | |||
Commit/backout must be explicitly specified within a daemon in order to effect the master’s transaction. | |||
Implicit commit on the daemon is never done. Normal end of the daemon does not affect the master. | |||
If the daemon procedure is cancelled, the master transaction is backed out. | |||
If the daemon procedure is abended, the master transaction is backed out and the APSY error proc is run on the master.</li> | |||
<li>If a non-transactional daemon is created: | |||
The master transaction is unaffected by the daemon. | |||
Both implicit and explicit commit affect the daemon transaction only. | |||
If the daemon procedure is cancelled, only the daemon transaction is backed out. | |||
If the daemon procedure is abended, both the daemon and master transaction are backed out and the APSY error proc is run on the master.</li> | |||
</ul> | |||
Each time that an APSY loads a new procedure, the various KSERRC flags are always cleared. So when an error procedure is called, the error flags are always zero. | |||
=====With commit exits===== | |||
With the commit exits feature, the commit exit essentially runs as a transactional daemon with the original user being a pseudo master. Lower level daemons follow normal daemon behavior. | |||
<p>If a commit exit is running, and the APSY fails, the APSY error exit is scheduled to run. If the APSY error exit exists, the original transaction unit will be unaffected, unless the exit specifically designates a commit/backout. If there is no APSY error exit, the original transaction unit is aborted with <code>ERROR 2971: Action disabled by commit exit</code> and the user is restarted.</p> | |||
===Message displays=== | |||
<p> | |||
<var class="product">Model 204</var> provides these message display options for subsystem users: </p> | |||
<ul> | <ul> | ||
<li>Disconnect message display</li> | <li>Disconnect message display</li> | ||
<li><var class="product">Model 204</var> informational message display</li> | <li><var class="product">Model 204</var> informational message display</li> | ||
<li><var class="product">Model 204</var> error message display | <li><var class="product">Model 204</var> error message display | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>When a message display option is selected, messages of that type are displayed on the user's terminal. If a message display option is not selected, all messages of that type are not displayed on the user's terminal. Note that if the display of any <var class="product">Model 204</var> type message is suppressed, messages for the corresponding type are not displayed on the user's terminal, but are written to the audit trail file (CCAAUDIT).</p> | <p> | ||
<p>Typically, subsystem applications are written so that all messages displayed on the user's terminal are produced by the subsystem and <var class="product">Model 204</var> messages are suppressed. </p> | When a message display option is selected, messages of that type are displayed on the user's terminal. If a message display option is not selected, all messages of that type are not displayed on the user's terminal. Note that if the display of any <var class="product">Model 204</var> type message is suppressed, messages for the corresponding type are not displayed on the user's terminal, but are written to the audit trail file (CCAAUDIT).</p> | ||
<p> | |||
Typically, subsystem applications are written so that all messages displayed on the user's terminal are produced by the subsystem and <var class="product">Model 204</var> messages are suppressed. </p> | |||
<p>Files and permanent groups contained within the subsystem definition can be designated as mandatory (the default) or optional members of the subsystem: </p> | |||
===File usage=== | |||
====Mandatory vs. optional members==== | |||
<p> | |||
Files and permanent groups contained within the subsystem definition can be designated as mandatory (the default) or optional members of the subsystem: </p> | |||
<ul> | <ul> | ||
<li>Mandatory members | <li>Mandatory members | ||
<p>If a subsystem procedure issues an OPEN or CLOSE command for a mandatory member, the command is ignored by <var class="product">Model 204</var> and the user's current privileges are not changed.</p> | <p> | ||
</li> | Mandatory files or groups are automatically opened by <var class="product">Model 204</var> when a user logs into a subsystem and automatically closed when the user leaves the subsystem. Subsystem requests can assume that all mandatory files are open and that they are physically consistent. The user's file privileges are those defined in the subsystem definition for the current user's SCLASS. The opening of a mandatory member cannot be prevented by the subsystem administrator with the <var>STOP FILE</var> command when the subsystem is active. A mandatory member cannot be accessed by another copy of <var class="product">Model 204</var> until the entire subsystem is stopped.</p> | ||
<li>Optional members | <p> | ||
<p>When an optional member is not in use, it can be processed by another copy of <var class="product">Model 204</var>. </p> | If a subsystem procedure issues an <var>OPEN</var> or <var>CLOSE</var> command for a mandatory member, the command is ignored by <var class="product">Model 204</var> and the user's current privileges are not changed.</p></li> | ||
</li> | |||
<li>Optional members | |||
<p> | |||
Optional files or groups provide the ability for a file or group to be stopped by a subsystem administrator (using the <var>STOP FILE</var> command) without stopping the entire subsystem. If a member is defined as optional, it is not automatically opened during the subsystem login. It must be opened by the application by using an OPEN/OPENC statement or command. The file privileges assigned are those specified in the subsystem definition for the current user's SCLASS. The member is closed (for that user only) when the user leaves the subsystem if a <var>CLOSE</var> command has not been issued.</p> | |||
<p> | |||
When an optional member is not in use, it can be processed by another copy of <var class="product">Model 204</var>. </p></li> | |||
</ul> | </ul> | ||
<p>Requests that reference mandatory or optional members can be precompiled. Files not contained in the subsystem definition can be opened and referenced within a subsystem application, but the requests that reference those files cannot be precompiled.</p> | <p> | ||
Requests that reference mandatory or optional members can be precompiled. Files not contained in the subsystem definition can be opened and referenced within a subsystem application, but the requests that reference those files cannot be precompiled. </p> | |||
<p>Subsystem files and permanent group members can also be designated automatic or manual:</p> | |||
====Automatic vs. manual members==== | |||
<p> | |||
Subsystem files and permanent group members can also be designated automatic or manual:</p> | |||
<ul> | <ul> | ||
<li>An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem. </li> | <li>An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem. </li> | ||
<li>A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command. | <li>A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>Mandatory files cannot be designated manual. Optional files can be designated either automatic or manual.</p> | <p> | ||
Mandatory files cannot be designated manual. Optional files can be designated either automatic or manual.</p> | |||
<p>The GROUP parameter of the subsystem definition applies | |||
====Permanent vs. temporary groups in subsystem definitions==== | |||
<p>[[#Summary of file definition options|Subsystem file definition options]] summarizes the subsystem file definition options. </p> | <p> | ||
The GROUP parameter of the subsystem definition applies <strong>only</strong> to permanent groups. Temporary group names cannot be used. To include temporary group members in a subsystem definition, and thus to enable their use in precompiled code, the members of the temporary group should be individually specified in the subsystem definition.</p> | |||
====Summary of file definition options==== | |||
<p> | |||
[[#Summary of file definition options|Subsystem file definition options]] summarizes the subsystem file definition options. </p> | |||
<table> | <table> | ||
<caption>Subsystem file definition options</caption> | <caption>Subsystem file definition options</caption> | ||
<tr class="head"> | <tr class="head"> | ||
<th>Subsystem definition option</th> | <th>Subsystem definition <br>option</th> | ||
<th>Automatic | <th>Automatic | ||
open and close?</th> | open <br>and close?</th> | ||
<th> | <th> | ||
Pre-compiled code?</th> | Pre-compiled <br>code?</th> | ||
<th>Start/stop file command allowed?</th> | <th>Start/stop file <br>command allowed?</th> | ||
<th> | <th>File privileges <br>assigned</th> | ||
File privileges assigned</th> | |||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Mandatory</td> | <td>Mandatory</td> | ||
Line 755: | Line 1,106: | ||
<td>SCLASS</td> | <td>SCLASS</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Optional</td> | <td>Optional</td> | ||
<td>Can be | <td>Can be automatic or manual</td> | ||
automatic or manual</td> | |||
<td>Yes</td> | <td>Yes</td> | ||
<td>Yes</td> | <td>Yes</td> | ||
<td>SCLASS</td> | <td>SCLASS</td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>None</td> | <td>None</td> | ||
<td>Cannot be | <td>Cannot be | ||
automatic</td> | automatic</td> | ||
<td>No</td> | <td>No</td> | ||
Line 773: | Line 1,125: | ||
</table> | </table> | ||
==Subsystem processing flow== | |||
<p>To design a subsystem, you must be familiar with the flow of control that occurs during subsystem processing. Subsystem processing typically involves the following phases:</p> | <p> | ||
To design a subsystem, you must be familiar with the flow of control that occurs during subsystem processing. Subsystem processing typically involves the following phases:</p> | |||
<table> | <table> | ||
<tr class="head"> | <tr class="head"> | ||
Line 780: | Line 1,133: | ||
<th>During this processing...</th> | <th>During this processing...</th> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Initialization </td> | <td>Initialization </td> | ||
<td>Subsystem is started and an optional initialization procedure is included. </td> | <td>Subsystem is started and an optional initialization procedure is included. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Login </td> | <td>Login </td> | ||
<td>User is logged into the subsystem; the user's privileges are determined by the subsystem definition. The appropriate required files and groups are opened for access. </td> | <td>User is logged into the subsystem; the user's privileges are determined by the subsystem definition. The appropriate required files and groups are opened for access. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Driver </td> | <td>Driver </td> | ||
<td>Procedures that make up the main body of the application are included. </td> | <td>Procedures that make up the main body of the application are included. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Disconnect </td> | <td>Disconnect </td> | ||
<td>All files and groups are closed for the user, who is then logged out of the subsystem. </td> | <td>All files and groups are closed for the user, who is then logged out of the subsystem. </td> | ||
</tr> | </tr> | ||
<tr> | <tr> | ||
<td>Error </td> | <td>Error </td> | ||
Line 801: | Line 1,159: | ||
</tr> | </tr> | ||
</table> | </table> | ||
<p>Initialization processing is invoked when the subsystem is started. A subsystem is started by the START SUBSYSTEM command, or, if the start option is indicated in the subsystem definition, when the first user enters the subsystem. </p> | ===Initialization processing=== | ||
<p>During subsystem initialization, <var class="product">Model 204</var> finds the subsystem definition and opens only required subsystem files and groups. If a required file or group cannot be opened, the subsystem initialization procedure terminates and the user is returned to command level.</p> | <p> | ||
<p>One of the subsystem components opened during initialization is the procedure file (or group, if a multiple-procedure group has been specified). The procedure file or group must contain all of the subsystem procedures that are included by the subsystem through the communication global variable. <var class="product">Model 204</var> scans the subsystem procedure file or group for all procedures whose names begin with either of the subsystem procedure prefixes. </p> | Initialization processing is invoked when the subsystem is started. A subsystem is started by the START SUBSYSTEM command, or, if the start option is indicated in the subsystem definition, when the first user enters the subsystem. </p> | ||
<p>The subsystem initialization procedure is included at this time. This is the only time during subsystem processing that the initialization procedure is executed.</p> | <p> | ||
<p>If no error occurs, <var class="product">Model 204</var> adds the subsystem name to the list of active subsystems. At this point, the subsystem is initialized and ready for use. </p> | During subsystem initialization, <var class="product">Model 204</var> finds the subsystem definition and opens only required subsystem files and groups. If a required file or group cannot be opened, the subsystem initialization procedure terminates and the user is returned to command level.</p> | ||
<p> | |||
<p>Login processing is invoked when a user enters a subsystem. If the automatic login option is indicated in the subsystem definition, <var class="product">Model 204</var> logs on the user using the subsystem name as the user ID. If the automatic login option is not indicated, the user's <var class="product">Model 204</var> user ID remains in use. </p> | One of the subsystem components opened during initialization is the procedure file (or group, if a multiple-procedure group has been specified). The procedure file or group must contain all of the subsystem procedures that are included by the subsystem through the communication global variable. <var class="product">Model 204</var> scans the subsystem procedure file or group for all procedures whose names begin with either of the subsystem procedure prefixes. </p> | ||
<p><var class="product">Model 204</var> next finds the user's subsystem user class definition in CCASYS and opens only the required subsystem files and groups with the privileges that are found for that user class. The MSGCTL parameter automatically is set for the user according to the subsystem definition. </p> | <p> | ||
<p><var class="product">Model 204</var> sets the communication global variable to the name of subsystem login procedure and proceeds into driver processing. </p> | The subsystem initialization procedure is included at this time. This is the only time during subsystem processing that the initialization procedure is executed.</p> | ||
<p> | |||
<p><var class="product">Model 204</var> determines which procedure to include next by examining the value of the communication global variable. The procedure name must be one of the names located by the scan of the procedure file during subsystem initialization. </p> | If no error occurs, <var class="product">Model 204</var> adds the subsystem name to the list of active subsystems. At this point, the subsystem is initialized and ready for use. </p> | ||
<p>If either the global variable or the procedure name cannot be found, the subsystem's error procedure is included. If an error procedure is not specified in the subsystem definition, the user is disconnected from the subsystem. </p> | |||
<p>If the procedure name is found, <var class="product">Model 204</var> determines which prefix begins the procedure name. Processing then occurs as follows:</p> | ===Login processing=== | ||
<p> | |||
Login processing is invoked when a user enters a subsystem. If the automatic login option is indicated in the subsystem definition, <var class="product">Model 204</var> logs on the user using the subsystem name as the user ID. If the automatic login option is not indicated, the user's <var class="product">Model 204</var> user ID remains in use. </p> | |||
<p> | |||
<var class="product">Model 204</var> next finds the user's subsystem user class definition in CCASYS and opens only the required subsystem files and groups with the privileges that are found for that user class. The MSGCTL parameter automatically is set for the user according to the subsystem definition. </p> | |||
<p> | |||
<var class="product">Model 204</var> sets the communication global variable to the name of subsystem login procedure and proceeds into driver processing. </p> | |||
===Driver processing=== | |||
<p> | |||
<var class="product">Model 204</var> determines which procedure to include next by examining the value of the communication global variable. The procedure name must be one of the names located by the scan of the procedure file during subsystem initialization. </p> | |||
<p> | |||
If either the global variable or the procedure name cannot be found, the subsystem's error procedure is included. If an error procedure is not specified in the subsystem definition, the user is disconnected from the subsystem. </p> | |||
<p> | |||
If the procedure name is found, <var class="product">Model 204</var> determines which prefix begins the procedure name. Processing then occurs as follows:</p> | |||
<ul> | <ul> | ||
<li>If the procedure name begins with the non-precompiled prefix, <var class="product">Model 204</var> includes the procedure for compilation and evaluation. </li> | <li>If the procedure name begins with the non-precompiled prefix, <var class="product">Model 204</var> includes the procedure for compilation and evaluation. </li> | ||
<li>If the procedure name begins with the precompiled prefix, <var class="product">Model 204</var> verifies whether the procedure was compiled previously with the set of privileges defined by the user's subsystem user class. | <li>If the procedure name begins with the precompiled prefix, <var class="product">Model 204</var> verifies whether the procedure was compiled previously with the set of privileges defined by the user's subsystem user class. | ||
<p>Once the compilation status of the procedure is determined, processing is as follows: </p | <p> | ||
Once the compilation status of the procedure is determined, processing is as follows: </p> | |||
<ul> | <ul> | ||
<li>If the procedure was not previously compiled successfully for the set of privileges defined by the user's subsystem user class, <var class="product">Model 204</var> includes the procedure for compilation and evaluation. If compilation is successful and no previous compilation was saved for the procedure, the contents of the compiler tables are saved in the system file CCATEMP.</li> | <li>If the procedure was not previously compiled successfully for the set of privileges defined by the user's subsystem user class, <var class="product">Model 204</var> includes the procedure for compilation and evaluation. If compilation is successful and no previous compilation was saved for the procedure, the contents of the compiler tables are saved in the system file CCATEMP.</li> | ||
<li>If the procedure was previously compiled successfully for the user's privilege set, <var class="product">Model 204</var> loads the contents of the compiler tables from CCATEMP and evaluates the request.</li> | <li>If the procedure was previously compiled successfully for the user's privilege set, <var class="product">Model 204</var> loads the contents of the compiler tables from CCATEMP and evaluates the request.</li> | ||
</ul></li> | |||
</ul> | </ul> | ||
< | <p> | ||
<var class="product">Model 204</var> repeats driver processing until the value of the communication global variable is set to the exit value specified in the subsystem definition. When the communication global variable is set to the exit value, <var class="product">Model 204</var> proceeds into disconnect processing. </p> | |||
<p>Disconnect processing is invoked when the subsystem application sets the communication variable to the exit value, when an error occurs with no subsystem error procedure, or when a subsystem user is restarted by <var class="product">Model 204</var>. During disconnect processing, <var class="product">Model 204</var> closes all required subsystem files and groups for the user, as well as any optional files and groups that have not been closed by the application. </p> | ===Disconnect processing=== | ||
<p>Depending upon whether the automatic logout option is indicated, the user is then either logged out of <var class="product">Model 204</var> or returned to the <var class="product">Model 204</var> command environment. </p> | <p> | ||
Disconnect processing is invoked when the subsystem application sets the communication variable to the exit value, when an error occurs with no subsystem error procedure, or when a subsystem user is restarted by <var class="product">Model 204</var>. During disconnect processing, <var class="product">Model 204</var> closes all required subsystem files and groups for the user, as well as any optional files and groups that have not been closed by the application. </p> | |||
<p>Error processing is invoked whenever a <var class="product">Model 204</var> error occurs that cannot be handled by the procedure being executed at the time. When an error is detected, <var class="product">Model 204</var> sets the value of the error global variable. </p> | <p> | ||
<p>If the subsystem has a defined error procedure, the error procedure is included at this time. If the subsystem does not have a defined error procedure, <var class="product">Model 204</var> proceeds into disconnect processing. </p> | Depending upon whether the automatic logout option is indicated, the user is then either logged out of <var class="product">Model 204</var> or returned to the <var class="product">Model 204</var> command environment. </p> | ||
<p>If the error trapped by the subsystem is a soft restart, a hard restart, or a terminal disconnect condition, the error procedure is invoked. The communication global variable is ignored when the error procedure completes and <var class="product">Model 204</var> proceeds with subsystem disconnect processing. </p> | |||
===Error processing=== | |||
<p> | |||
<p>This section introduces several terms and concepts which are unique to subsystems that reference remote files and scattered groups. These concepts, and related design considerations, are discussed in greater detail in | Error processing is invoked whenever a <var class="product">Model 204</var> error occurs that cannot be handled by the procedure being executed at the time. When an error is detected, <var class="product">Model 204</var> sets the value of the error global variable. </p> | ||
<p> | |||
<p>Parallel Query Option/204 provides access to remote files under the Subsystem Management facility by allowing the system manager to define client and service subsystems:</p> | If the subsystem has a defined error procedure, the error procedure is included at this time. If the subsystem does not have a defined error procedure, <var class="product">Model 204</var> proceeds into disconnect processing. </p> | ||
<p> | |||
If the error trapped by the subsystem is a soft restart, a hard restart, or a terminal disconnect condition, the error procedure is invoked. The communication global variable is ignored when the error procedure completes and <var class="product">Model 204</var> proceeds with subsystem disconnect processing. </p> | |||
==Parallel Query Option/204 (PQO) considerations== | |||
<p> | |||
This section introduces several terms and concepts which are unique to subsystems that reference remote files and scattered groups. These concepts, and related design considerations, are discussed in greater detail in [[PQO: Scattered APSY subsystems]]. </p> | |||
===Remote file access=== | |||
<p> | |||
Parallel Query Option/204 provides access to remote files under the Subsystem Management facility by allowing the system manager to define client and service subsystems:</p> | |||
<ul> | <ul> | ||
<li>A client subsystem is the subsystem a user is running in when requesting access to remote data. </li> | <li>A client subsystem is the subsystem a user is running in when requesting access to remote data. </li> | ||
<li>A service subsystem is the subsystem on a server node that a client user's service thread is logged into. | <li>A service subsystem is the subsystem on a server node that a client user's service thread is logged into. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>A service subsystem definition is stored in the CCASYS file on each node that the client subsystem accesses. The name of a subsystem must be the same at each node. The location of the client node is included in the subsystem name to uniquely identify it to the server node.</p> | <p> | ||
A service subsystem definition is stored in the CCASYS file on each node that the client subsystem accesses. The name of a subsystem must be the same at each node. The location of the client node is included in the subsystem name to uniquely identify it to the server node.</p> | |||
<p>A server node can be available or unavailable to a client subsystem.</p> | |||
===Node availability=== | |||
<p> | |||
A server node can be available or unavailable to a client subsystem.</p> | |||
<ul> | <ul> | ||
<li>A node is available if the service subsystem has been successfully started. </li> | <li>A node is available if the service subsystem has been successfully started. </li> | ||
<li>If the service subsystem has not been started, it does not have a subsystem definition structure accessible to the client and is therefore unavailable. | <li>If the service subsystem has not been started, it does not have a subsystem definition structure accessible to the client and is therefore unavailable. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>A node can only be marked unavailable during start processing if there are mandatory members on a server node and the service subsystem cannot be started. If this happens, start processing also fails on the client node.</p> | <p> | ||
<p>Client subsystems attempting to access service subsystems that are not started receive an error message from the server node. </p> | A node can only be marked unavailable during start processing if there are mandatory members on a server node and the service subsystem cannot be started. If this happens, start processing also fails on the client node.</p> | ||
<p>A previously available node can become unavailable when: </p> | <p> | ||
Client subsystems attempting to access service subsystems that are not started receive an error message from the server node. </p> | |||
<p> | |||
A previously available node can become unavailable when: </p> | |||
<ul> | <ul> | ||
<li>Resumption of communication fails after recovering from a system failure.</li> | <li>Resumption of communication fails after recovering from a system failure.</li> | ||
<li>A user attempts to log into the service subsystem by logging into the client subsystem, the service subsystem definition is not found, and at least one mandatory member resides on that node.</li> | <li>A user attempts to log into the service subsystem by logging into the client subsystem, the service subsystem definition is not found, and at least one mandatory member resides on that node.</li> | ||
<li>A user attempts to open a file on a node where the user was not previously logged in. | <li>A user attempts to open a file on a node where the user was not previously logged in. </li> | ||
</li> | |||
</ul> | </ul> | ||
<p>The user is automatically logged into all associated service subsystems when entering a subsystem that contains remote files. If the service subsystem is unavailable on a node, the user cannot be logged in. </p> | <p> | ||
The user is automatically logged into all associated service subsystems when entering a subsystem that contains remote files. If the service subsystem is unavailable on a node, the user cannot be logged in. </p> | |||
<p>The members of a subsystem are files and permanent groups. With Parallel Query Option/204, members can be either automatic or manual: </p> | |||
===File and group availability=== | |||
<p> | |||
The members of a subsystem are files and permanent groups. With Parallel Query Option/204, members can be either automatic or manual: </p> | |||
<ul> | <ul> | ||
<li>An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem. </li> | <li>An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem. </li> | ||
<li>A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command. | <li>A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>Members can also be either mandatory or optional:</p> | <p> | ||
Members can also be either mandatory or optional:</p> | |||
<ul> | <ul> | ||
<li>A mandatory member must be open in order to access a subsystem. Mandatory members cannot be manual.</li> | <li>A mandatory member must be open in order to access a subsystem. Mandatory members cannot be manual.</li> | ||
<li>An optional member is not required for subsystem access (start and login processing can succeed without it). | <li>An optional member is not required for subsystem access (start and login processing can succeed without it). | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>At any given time a member can be open or closed to a subsystem or to a user within a subsystem. The following sections explain the conditions under which the different kinds of members are accessible to APSY subsystems and their users.</p> | <p> | ||
At any given time a member can be open or closed to a subsystem or to a user within a subsystem. The following sections explain the conditions under which the different kinds of members are accessible to APSY subsystems and their users.</p> | |||
<p>Automatic members of subsystems are always opened by the START SUBSYSTEM command or by SUBSYSTEM LOGIN. At the end of START processing, each automatic member is open unless either the START or OPEN failed. </p> | |||
<p>Manual members of subsystems are in the closed state at the completion of START SUBSYSTEM processing and must be explicitly opened by the user. Manual members become open to the subsystem if an OPEN operation succeeds. If OPEN fails due to node unavailability or for user-specific reasons (for example, if the user's line goes down) the member remains closed to the subsystem.</p> | ====Member availability to subsystems==== | ||
<p>If a node becomes unavailable to a subsystem, all automatic subsystem members and all open manual subsystem members residing on the unavailable node are marked disabled.</p> | <p> | ||
<p>If a STOP FILE/GROUP command is issued for a manual member on the client subsystem's node, the member is closed to the client subsystem when the last user closes it. If the member is located on the service subsystem node, the file is closed to the service subsystem when the STOP is complete or the last user closes the file.</p> | Automatic members of subsystems are always opened by the START SUBSYSTEM command or by SUBSYSTEM LOGIN. At the end of START processing, each automatic member is open unless either the START or OPEN failed. </p> | ||
<p> | |||
<p>When a user enters a subsystem, automatic subsystem members are opened.</p> | Manual members of subsystems are in the closed state at the completion of START SUBSYSTEM processing and must be explicitly opened by the user. Manual members become open to the subsystem if an OPEN operation succeeds. If OPEN fails due to node unavailability or for user-specific reasons (for example, if the user's line goes down) the member remains closed to the subsystem.</p> | ||
<p>If a user LOGIN or OPEN operation fails for an optional member, the member is left closed for the user but remains available to the subsystem. If a mandatory member cannot be opened, the user is denied access to the subsystem.</p> | <p> | ||
<p>If a user LOGIN or OPEN operation fails for an already open member, the member is left disabled for the user but remains open to the subsystem. </p> | If a node becomes unavailable to a subsystem, all automatic subsystem members and all open manual subsystem members residing on the unavailable node are marked disabled.</p> | ||
<p>If an automatic mandatory member is closed to the subsystem, new users are not allowed to enter the subsystem.</p> | <p> | ||
<p>Manual members of subsystems are closed for a user within a subsystem until the user issues an OPEN command or statement. In this case it does not matter whether the member is open or closed to the subsystem.</p> | If a STOP FILE/GROUP command is issued for a manual member on the client subsystem's node, the member is closed to the client subsystem when the last user closes it. If the member is located on the service subsystem node, the file is closed to the service subsystem when the STOP is complete or the last user closes the file.</p> | ||
<p>If compilation and/or loading of a request fails due to a communications failure, previously opened members on the failing node become disabled to the user. </p> | |||
<p>A user can close optional members at any time by issuing the CLOSE command.</p> | ====Member availability to subsystem users==== | ||
<p> | |||
<p>In the event that a subsystem file or group is marked disabled, you can enable it (after correcting the problem) without having to bring the subsystem down. To do this, use the ENABLE SUBSYSTEM command:</p> | When a user enters a subsystem, automatic subsystem members are opened.</p> | ||
<p> | |||
<p class="syntax">ENABLE SUBSYSTEM <span class="term">subsysname</span> | If a user LOGIN or OPEN operation fails for an optional member, the member is left closed for the user but remains available to the subsystem. If a mandatory member cannot be opened, the user is denied access to the subsystem.</p> | ||
<p> | |||
[FILE <span class="term">name</span> AT <span class="term">location</span> | GROUP <span class="term">name</span>] | If a user LOGIN or OPEN operation fails for an already open member, the member is left disabled for the user but remains open to the subsystem. </p> | ||
<p> | |||
If an automatic mandatory member is closed to the subsystem, new users are not allowed to enter the subsystem.</p> | |||
<p> | |||
Manual members of subsystems are closed for a user within a subsystem until the user issues an OPEN command or statement. In this case it does not matter whether the member is open or closed to the subsystem.</p> | |||
<p> | |||
If compilation and/or loading of a request fails due to a communications failure, previously opened members on the failing node become disabled to the user. </p> | |||
<p> | |||
A user can close optional members at any time by issuing the CLOSE command.</p> | |||
====Enabling disabled subsystem files==== | |||
<p> | |||
In the event that a subsystem file or group is marked disabled, you can enable it (after correcting the problem) without having to bring the subsystem down. To do this, use the ENABLE SUBSYSTEM command:</p> | |||
====Syntax==== | |||
<p class="syntax">ENABLE SUBSYSTEM <span class="term">subsysname</span> | |||
[FILE <span class="term">name</span> AT <span class="term">location</span> <span class="squareb">|</span> GROUP <span class="term">name</span>] | |||
</p> | </p> | ||
Where: | |||
<ul> | <ul> | ||
<li>< | <li><var class="term">subsysname</var> is the name of the client subsystem</li> | ||
<li>< | <li><var class="term">location</var> is the name of the remote node where the file is stored. Note that the location must be explicitly specified; you cannot reference local files with the ENABLE SUBSYSTEM command. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>You can make a subsystem file or group (or an entire subsystem, if a file is mandatory) temporarily inaccessible without having to bring the subsystem down, using the DISABLE SUBSYSTEM command:</p> | ====Intentionally disabling a subsystem file==== | ||
<p class="syntax">DISABLE SUBSYSTEM <span class="term">subsysname</span> | <p> | ||
You can make a subsystem file or group (or an entire subsystem, if a file is mandatory) temporarily inaccessible without having to bring the subsystem down, using the DISABLE SUBSYSTEM command:</p> | |||
[FILE <span class="term">name</span> AT <span class="term">location</span> | GROUP <span class="term">name</span>] | <p class="syntax">DISABLE SUBSYSTEM <span class="term">subsysname</span> | ||
[FILE <span class="term">name</span> AT <span class="term">location</span> <span class="squareb">|</span> GROUP <span class="term">name</span>] | |||
</p> | </p> | ||
<p>When a file or group is intentionally disabled with the DISABLE SUBSYSTEM command, subsystem behavior is exactly the same as when a communications failure causes the disabling. This behavior is described in [[#File and group availability|File and group availability]].</p> | <p> | ||
When a file or group is intentionally disabled with the DISABLE SUBSYSTEM command, subsystem behavior is exactly the same as when a communications failure causes the disabling. This behavior is described in [[#File and group availability|File and group availability]].</p> | |||
<p>As an alternative to the privilege settings normally available through the Subsystem Management facility, the system manager at a service node can control client subsystem access by creating a trust definition for the client subsystem. If a client subsystem is fully or partially trusted, the trust definition is sufficient for maintaining the relationship with the client; the system manager at the service node does not have to create and maintain a separate set of file and SCLASS definitions for the client subsystem.</p> | |||
<p>For example, suppose a subsystem located on a node named DETROIT (the client node) includes in its definition files located on a node named CLEVELAND (the service node). Further, suppose the subsystem is fully or partially trusted by CLEVELAND. In this case, the file and SCLASS definitions are maintained only on the client node (DETROIT), and the service node (CLEVELAND) needs only to maintain the trust definition.</p> | ===Trust=== | ||
<p>The four levels of trust available with Parallel Query Option/204 are:</p> | <p> | ||
As an alternative to the privilege settings normally available through the Subsystem Management facility, the system manager at a service node can control client subsystem access by creating a trust definition for the client subsystem. If a client subsystem is fully or partially trusted, the trust definition is sufficient for maintaining the relationship with the client; the system manager at the service node does not have to create and maintain a separate set of file and SCLASS definitions for the client subsystem.</p> | |||
<p> | |||
For example, suppose a subsystem located on a node named DETROIT (the client node) includes in its definition files located on a node named CLEVELAND (the service node). Further, suppose the subsystem is fully or partially trusted by CLEVELAND. In this case, the file and SCLASS definitions are maintained only on the client node (DETROIT), and the service node (CLEVELAND) needs only to maintain the trust definition.</p> | |||
<p> | |||
The four levels of trust available with Parallel Query Option/204 are:</p> | |||
<ul> | <ul> | ||
<li>< | <li><b>Full trust</b> | ||
</li> | <p> | ||
<li>< | Only the subsystem name and location appear on the service node's definition, which you create on the Subsystem Trust screen.</p></li> | ||
<li><b>Partial trust</b> | |||
<p> | |||
Along with the subsystem name and location, you can specify maximum file privileges. In this case, the client subsystem is trusted, but the maximum file privileges and field level security levels specified on the Subsystem Trust screen cannot be exceeded.</p> | |||
<ul> | <ul> | ||
<li>If a user requests file privileges that would exceed the maximum, the service node does not open the file to that user.</li> | <li>If a user requests file privileges that would exceed the maximum, the service node does not open the file to that user.</li> | ||
<li>If a user requests a field level security status that would exceed the maximum, <var class="product">Model 204</var> automatically resets the request to the allowed level (that is, the maximum) and opens the file to that user.</li> | <li>If a user requests a field level security status that would exceed the maximum, <var class="product">Model 204</var> automatically resets the request to the allowed level (that is, the maximum) and opens the file to that user.</li> | ||
</ul> | </ul></li> | ||
<li>< | |||
<li><b>Restricted trust</b> | |||
<p> | |||
For a subsystem that has a restricted trust definition, you make no entries on the Subsystem Trust screen. A restricted trust definition is based solely on entries you make on these five screens:</p> | |||
<ul> | <ul> | ||
<li>Subsystem Activity</li> | <li>Subsystem Activity</li> | ||
Line 937: | Line 1,358: | ||
<li>Subsystem Class Users</li> | <li>Subsystem Class Users</li> | ||
</ul> | </ul> | ||
<p>The accessibility of service node files to a client subsystem is determined by the SCLASS, user, and file privileges that you specify on these screens. </p> | <p> | ||
The accessibility of service node files to a client subsystem is determined by the SCLASS, user, and file privileges that you specify on these screens. </p> | |||
</li> | </li> | ||
<li>< | |||
<li><b>No trust</b> | |||
<p> | |||
No subsystem service definition exists for the subsystem. The client subsystem cannot access any files on the service node as subsystem files. The files on the service node can, however, be accessed from within a client subsystem as individual, non-subsystem files if the following criteria are met:</p> | |||
<ul> | <ul> | ||
<li>Parallel Query Option/204 is installed at both sites.</li> | <li>Parallel Query Option/204 is installed at both sites.</li> | ||
<li>Horizon is installed at both sites, and there are link, processgroup, and process definitions connecting the client node to the service node.</li> | <li>Horizon is installed at both sites, and there are link, processgroup, and process definitions connecting the client node to the service node.</li> | ||
<li>For any given file, the value of the OPENCTL parameter allows remote access (X'02', X'04', or X'08') | <li>For any given file, the value of the <var>[[OPENCTL parameter|OPENCTL]]</var> parameter allows remote access (X'02', X'04', or X'08'). </li> | ||
</ul> | </ul> | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>See the < | <p> | ||
See the | |||
<var class="book">Rocket Parallel Query Option/204 User's Guide</var> for detailed information on creating and managing trust definitions.</p> | |||
==Subsystem design considerations== | |||
<p>This section presents coding considerations for subsystem procedures. Some of the guidelines listed below also appear in earlier sections. They are consolidated here for the convenience of the application developer. </p> | <p> | ||
This section presents coding considerations for subsystem procedures. Some of the guidelines listed below also appear in earlier sections. They are consolidated here for the convenience of the application developer. </p> | |||
===Coding considerations=== | |||
<ul> | <ul> | ||
<li>Procedures should be small and modular.</li> | <li>Procedures should be small and modular.</li> | ||
<li>Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.</li> | <li>Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.</li> | ||
<li>Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.</li> | <li>Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.</li> | ||
<li>The communication global variable must be set to the exit value in order to exit the subsystem. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used.</li> | <li>The communication global variable must be set to the exit value in order to exit the subsystem. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used.</li> | ||
<li>Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.</li> | <li>Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.</li> | ||
<li>Non-subsystem files can be opened and referenced only by non-precompiled procedures.</li> | <li>Non-subsystem files can be opened and referenced only by non-precompiled procedures.</li> | ||
<li>Precompiled procedures cannot reference PERM groups that are not members of the same subsystem.</li> | <li>Precompiled procedures cannot reference PERM groups that are not members of the same subsystem.</li> | ||
<li>Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.</li> | <li>Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.</li> | ||
<li>The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem. </li> | <li>The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem. </li> | ||
<li>Distinct group numbers are assigned to optional groups at START SUBSYSTEM time. Those numbers cannot be used by non-subsystem members opened within the subsystem. Thus the NGROUP limit used for earlier releases might be exceeded during either START or OPEN processing inside the subsystem.</li> | <li>Distinct group numbers are assigned to optional groups at START SUBSYSTEM time. Those numbers cannot be used by non-subsystem members opened within the subsystem. Thus the NGROUP limit used for earlier releases might be exceeded during either START or OPEN processing inside the subsystem.</li> | ||
<li>To prevent you from having the wrong file or group privileges in a subsystem, <var class="product">Model 204</var> closes optional files and groups before entering a subsystem. In earlier releases, optional files and groups were only closed when you left the subsystem. | <li>To prevent you from having the wrong file or group privileges in a subsystem, <var class="product">Model 204</var> closes optional files and groups before entering a subsystem. In earlier releases, optional files and groups were only closed when you left the subsystem. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>Users should be aware of the following conditions when coding applications to run under the Subsystem Management facility:</p> | <p> | ||
Users should be aware of the following conditions when coding applications to run under the Subsystem Management facility:</p> | |||
<ul> | <ul> | ||
<li>Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.</li> | <li>Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.</li> | ||
<li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | <li>If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.</li> | ||
<li>A subsystem procedure cannot issue the CREATE command for a subsystem file.</li> | <li>A subsystem procedure cannot issue the CREATE command for a subsystem file.</li> | ||
<li>LXTBL and LFTBL cannot be reset from within a subsystem procedure.</li> | <li>LXTBL and LFTBL cannot be reset from within a subsystem procedure.</li> | ||
<li>All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed. | <li>All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed. | ||
<p>The default action for each type of message is listed in | <p> | ||
<p>If you do not wish the default action to be executed, you need to add a message handler routine to the procedure containing the statement that invokes the message. </p> | The default action for each type of message is listed in [[M204.1076]]. </p> | ||
<p> | |||
If you do not wish the default action to be executed, you need to add a message handler routine to the procedure containing the statement that invokes the message. </p> | |||
</li> | </li> | ||
</ul> | </ul> | ||
<p>To keep track of the files referenced in a subsystem procedure, which cannot exceed 6,043 files | ====Keeping track of the number of files referenced==== | ||
<p> | |||
To keep track of the files referenced in a subsystem procedure, which cannot exceed 6,043 files — a CCATEMP page, use the following formula:</p> | |||
<p class="code">NFILE + NRFILE + 1 (for CCAGRP) + 1 (for CCASYS) | <p class="code">NFILE + NRFILE + 1 (for CCAGRP) + 1 (for CCASYS) | ||
</p> | </p> | ||
<p>Depending upon the subsystem definition, <var class="product">Model 204</var> might place a share lock on one or more subsystem procedure names or group names. </p> | ==Record locking considerations== | ||
<p>If the subsystem is defined with permanent groups, <var class="product">Model 204</var> locks the group names to ensure that the group definitions do not change while the subsystem is running. A share lock is maintained for each group while the subsystem is active. </p> | <p> | ||
Depending upon the subsystem definition, <var class="product">Model 204</var> might place a share lock on one or more subsystem procedure names or group names. </p> | |||
<p>If the subsystem definition specifies that subsystem files are unlocked, <var class="product">Model 204</var> locks in share mode each of the subsystem procedures to ensure that the procedures do not change or move. This prevents any user from:</p> | <p> | ||
If the subsystem is defined with permanent groups, <var class="product">Model 204</var> locks the group names to ensure that the group definitions do not change while the subsystem is running. A share lock is maintained for each group while the subsystem is active. </p> | |||
===If subsystem files are defined as unlocked=== | |||
<p> | |||
If the subsystem definition specifies that subsystem files are unlocked, <var class="product">Model 204</var> locks in share mode each of the subsystem procedures to ensure that the procedures do not change or move. This prevents any user from:</p> | |||
<ul> | <ul> | ||
<li>Issuing the DELETE PROCEDURE command</li> | <li>Issuing the DELETE PROCEDURE command</li> | ||
<li>Issuing the RENAME PROCEDURE command</li> | <li>Issuing the RENAME PROCEDURE command</li> | ||
<li>Updating the procedure while the subsystem is active. | <li>Updating the procedure while the subsystem is active. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>The User Language functions, [[$ | ==Subsystem procedure control functions== | ||
<p> | |||
<p>The $ | The User Language functions, [[$Sclass#$Sclass|$Sclass]] and [[$Subsys#$Subsys|$Subsys]] can be useful in determining subsystem program control.</p> | ||
<p class="code"> BRANCH: JUMP TO (ADD.REC, VIEW.REC, UPD.REC) - | |||
===$Sclass function=== | |||
<p> | |||
The $Sclass function returns the Sclass name of the current user. $Sclass is useful when the transfer of control is dependent upon a user's privileges. For example:</p> | |||
<p class="code"> BRANCH: JUMP TO (ADD.REC, VIEW.REC, UPD.REC) - | |||
%MAIN.MENU:SELECTION | %MAIN.MENU:SELECTION | ||
. | . | ||
. | . | ||
. | . | ||
UPD.REC: IF $ | UPD.REC: IF $sclass = 'READ' THEN | ||
IF $SETG('NEXT','PRE-RPT.PGM') THEN | IF $SETG('NEXT','PRE-RPT.PGM') THEN | ||
PRINT 'GLOBAL TABLE FULL' | PRINT 'GLOBAL TABLE FULL' | ||
END IF | END IF | ||
ELSEIF $ | ELSEIF $sclass = 'UPDATE' THEN | ||
IF $ | IF $setg('NEXT','PRE-MAINT.PGM') THEN | ||
PRINT 'GLOBAL TABLE FULL' | PRINT 'GLOBAL TABLE FULL' | ||
END IF | END IF | ||
. | . | ||
. | . | ||
. | . | ||
</p> | </p> | ||
<p>The $ | ===$Subsys function=== | ||
<p> | |||
<p>This section describes three <var class="product">Model 204</var> features that are useful in developing, testing and debugging subsystem procedures:</p> | The $Subsys function returns a numeric value indicating the status of a subsystem, or the name of the current subsystem (if no argument is specified). $Subsys often is used to determine whether a subsystem is active before a transfer is attempted. </p> | ||
==Subsystem development tools== | |||
<p> | |||
This section describes three <var class="product">Model 204</var> features that are useful in developing, testing and debugging subsystem procedures:</p> | |||
<ul> | <ul> | ||
<li>The DEBUG and TEST commands, which assist subsystem debugging by allowing you to display the global communications variable and specify the next procedure to be INCLUDEd.</li> | <li>The <var>[[DEBUG command|DEBUG]]</var> and <var>[[TEST command|TEST]]</var> commands, which assist subsystem debugging by allowing you to display the global communications variable and specify the next procedure to be INCLUDEd.</li> | ||
<li>Multiple procedure file groups, which allow users to change procedures without stopping the subsystem or interfering with other users.</li> | <li>Multiple procedure file groups, which allow users to change procedures without stopping the subsystem or interfering with other users.</li> | ||
<li>The Cross-Reference facility, which produces reports on the variable names, global dummy strings, and other language elements used in a specified set of User Language procedures. </li> | <li>The Cross-Reference facility, which produces reports on the variable names, global dummy strings, and other language elements used in a specified set of User Language procedures. </li> | ||
</ul> | </ul> | ||
<p>The <var class="product">Model 204</var> DEBUG and TEST SUBSYSTEM commands assist you in debugging subsystem code while it is being developed. Both commands display the value of the communication global variable, prompt you for changes, and display since-last statistics. </p> | ===Debugging and testing facilities=== | ||
<p>DEBUG differs from TEST SUBSYSTEM in the following ways:</p> | <p> | ||
The <var class="product">Model 204</var> DEBUG and TEST SUBSYSTEM commands assist you in debugging subsystem code while it is being developed. Both commands display the value of the communication global variable, prompt you for changes, and display since-last statistics. </p> | |||
<p> | |||
DEBUG differs from TEST SUBSYSTEM in the following ways:</p> | |||
<ul> | <ul> | ||
<li>DEBUG can be executed by more than one user in the same subsystem at the same time; TEST SUBSYSTEM can only be executed by a single user.</li> | <li>DEBUG can be executed by more than one user in the same subsystem at the same time; TEST SUBSYSTEM can only be executed by a single user.</li> | ||
<li>To execute TEST SUBSYSTEM, the user must stop the subsystem, which will be restarted in single user mode as a result of issuing the TEST command. To execute DEBUG, the user does not have to stop the subsystem. The DEBUG command can be issued for any subsystem that has been started, or for any subsystem that has the AUTOSTART feature.</li> | <li>To execute TEST SUBSYSTEM, the user must stop the subsystem, which will be restarted in single user mode as a result of issuing the TEST command. To execute DEBUG, the user does not have to stop the subsystem. The DEBUG command can be issued for any subsystem that has been started, or for any subsystem that has the AUTOSTART feature.</li> | ||
<li>Since-last statistics are provided automatically with DEBUG; they are optional with TEST. | <li>Since-last statistics are provided automatically with DEBUG; they are optional with TEST. | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>In general, the DEBUG command is more convenient for subsystem developers in a multiuser environment.</p> | <p> | ||
<p>To execute the DEBUG command, the user must be named to an SCLASS which has been granted either the TEST or DEBUG privilege. The DEBUG privilege does not entitle the user to execute the TEST command.</p> | In general, the DEBUG command is more convenient for subsystem developers in a multiuser environment.</p> | ||
<p> | |||
<p>The format of the DEBUG command is: </p> | To execute the DEBUG command, the user must be named to an SCLASS which has been granted either the TEST or DEBUG privilege. The DEBUG privilege does not entitle the user to execute the TEST command.</p> | ||
<p class=" | |||
====Syntax==== | |||
<p> | |||
The format of the DEBUG command is: </p> | |||
<p class="syntax">DEBUG SUBSYSTEM <span class="term">subsystemname</span> [<span class="term">parameters</span>] | |||
</p> | </p> | ||
<p>The extended format of the TEST command is:</p> | <p> | ||
<p class=" | The extended format of the TEST command is:</p> | ||
<p class="syntax">TEST [DEBUG] [STATS] [SUBSYSTEM] <span class="term">subsystemname</span> <span class="term">parameters</span> | |||
</p> | </p> | ||
Where: | |||
<ul> | <ul> | ||
<li>DEBUG specifies that the communication global variable is displayed on the user's terminal before the next procedure is included. The user then has the option of specifying a different procedure to be included next. If the user presses <var>ENTER</var> without specifying a different procedure, the procedure whose name is currently displayed is included next. </li> | <li>DEBUG specifies that the communication global variable is displayed on the user's terminal before the next procedure is included. The user then has the option of specifying a different procedure to be included next. If the user presses <var>ENTER</var> without specifying a different procedure, the procedure whose name is currently displayed is included next. </li> | ||
<li>STATS specifies that since-last statistics are displayed on the user's terminal after each procedure is evaluated. Since-last statistics are described in | <li>STATS specifies that since-last statistics are displayed on the user's terminal after each procedure is evaluated. Since-last statistics are described in [[Using system statistics#User since-last statistics|User since-last statistics]]. </li> | ||
<li>SUBSYSTEM specifies that the word following the keyword is the name of a subsystem and that parameters follow the subsystem name. This keyword can be used to eliminate confusion when DEBUG or STATS is the name of a subsystem or subsystem parameter. </li> | <li>SUBSYSTEM specifies that the word following the keyword is the name of a subsystem and that parameters follow the subsystem name. This keyword can be used to eliminate confusion when DEBUG or STATS is the name of a subsystem or subsystem parameter. </li> | ||
< | |||
< | <li><i>parameters</i> specifies the parameters to be stored in the command line global variable. The parameter information can be as many as 255 characters in length. | ||
</li> | </li> | ||
</ul> | </ul> | ||
===Multiple procedure files=== | |||
<p>If | <p> | ||
<p>Multiple procedure file groups make it possible to change subsystem procedures without having to stop the subsystem. This is accomplished by setting GROUP | If <code>PROCFILE=*</code> is specified when a group is created, then several files in a group can contain procedures. When the <var>INCLUDE</var> command is executed in the context of a multiple procedure file group, files are searched, left to right, in the order they were defined in the original <var>CREATE GROUP</var> command.</p> | ||
<p>The multiple procedure file option also allows different users to make changes to procedures in the same subsystem without interfering with each other. The | <p> | ||
<p>The following restrictions apply to the use of | Multiple procedure file groups make it possible to change subsystem procedures without having to stop the subsystem. This is accomplished by setting <b>GROUP</b> to <code>Y</code> for the subsystem's procedure file in the subsystem definition, and by specifying a number value for <b>Procs NUMLK</b> that is less than the number of files in the group. The application subsystem locks the procedures in the last (or rightmost) NUMLK number of files, as determined by the right-to-left order they were specified in the <var>CREATE GROUP</var> command that defined the procedure group. For an example, see [[System requirements for Application Subsystems#Subsystem File Use screen|Subsystem File Use screen]].</p> | ||
<p> | |||
The multiple procedure file option also allows different users to make changes to procedures in the same subsystem without interfering with each other. The procedure group specified in the subsystem definition must have a corresponding <var>CREATE PERM GROUP</var> definition. However, any individual user can create or open a temporary group with the same name as the subsystem's permanent procedure group. If a user has such a temporary group open and enters a subsystem, the subsystem uses the temporary group instead of the subsystem's permanent group. </p> | |||
<p> | |||
The following restrictions apply to the use of temporary groups to store subsystem procedure files:</p> | |||
<ul> | <ul> | ||
<li>The user's SCLASS must have the TEST or DEBUG privilege.</li> | <li>The user's SCLASS must have the <var>TEST</var> or <var>DEBUG</var> privilege.</li> | ||
<li>The last n files of the PERM GROUP (where n is set by the NUMLK parameter) must correspond exactly to the last n files of the TEMP GROUP | <li>The last <i>n</i> files of the <var>CREATE PERM GROUP</var> command (where <i>n</i> is set by the <code>NUMLK</code> parameter) must correspond exactly to the last <i>n</i> files of the <var>CREATE TEMP GROUP</var> command. </li> | ||
</li> | |||
</ul> | </ul> | ||
===Cross-Reference facility=== | |||
<p>The Cross-Reference facility is a Dictionary facility that can be invoked from both the Dictionary Main Menu and <var class="product">Model 204</var> command level. It produces reports for users who develop and maintain <var class="product">Model 204</var> User Language procedures.</p> | <p> | ||
<p>The output reports show the line numbers where language elements such as labels, functions, images and variable names occur in a specified set of procedures. Elements within subroutines and nested INCLUDEs can also be cross-referenced.</p> | The Cross-Reference facility is a Dictionary facility that can be invoked from both the Dictionary Main Menu and <var class="product">Model 204</var> command level. It produces reports for users who develop and maintain <var class="product">Model 204</var> User Language procedures.</p> | ||
<p>The Cross-Reference Report is produced in batch mode (by a batch job in OS and DOS, by a service machine in CMS). Prior to submitting a cross-reference job, the user can specify:</p> | <p> | ||
The output reports show the line numbers where language elements such as labels, functions, images and variable names occur in a specified set of procedures. Elements within subroutines and nested INCLUDEs can also be cross-referenced.</p> | |||
<p> | |||
The Cross-Reference Report is produced in batch mode (by a batch job in OS and DOS, by a service machine in CMS). Prior to submitting a cross-reference job, the user can specify:</p> | |||
<ul> | <ul> | ||
<li>A set of procedures in a procedure file or group</li> | <li>A set of procedures in a procedure file or group</li> | ||
<li>A set of language elements to be cross referenced</li> | <li>A set of language elements to be cross referenced</li> | ||
<li>Substitute values for User Language global dummy strings</li> | <li>Substitute values for User Language global dummy strings</li> | ||
<li>Job-related parameters such as output destination and lines per page | <li>Job-related parameters such as output destination and lines per page | ||
</li> | </li> | ||
</ul> | </ul> | ||
<p>The Cross-Reference facility also includes Preview and Browse functions, which inform the user about the procedures selected for processing.</p> | <p> | ||
<p>For a complete description of the Cross-Reference facility, refer to the | The Cross-Reference facility also includes Preview and Browse functions, which inform the user about the procedures selected for processing.</p> | ||
<p> | |||
For a complete description of the Cross-Reference facility, refer to the [[:Category:Dictionary/204#Dictionary/204 topics|Dictionary/204 topics]].</p> | |||
[[Category:SOUL]] | [[Category:SOUL]] |
Latest revision as of 22:16, 25 April 2022
Overview
Although only a system manager can define a subsystem, the determination of a subsystem's options and components typically also involves the file manager and application developer. This page focuses on subsystem facility topics most relevant to the application developer:
The Subsystem Management facility of Dictionary lets you define a collection of procedures to Model 204 as a subsystem and to assign certain characteristics to that subsystem.
Advantages of subsystems
The following table summarizes the advantages of subsystems over other SOUL procedure applications:
Advantage | Subsystems... |
---|---|
Minimal end-user intervention | Require minimal knowledge of Model 204. The end user need not know what files and procedures exist for the application. The subsystem is invoked simply by entering the subsystem name as a Model 204 command. |
Driver facility | Eliminate the need for user-written drivers containing conditional INCLUDEs based on a global variable. This driver facility leads to smaller, more modular procedures that are easier to maintain and enhance. |
Performance improvements | Improve performance by saving and reloading compiled SOUL requests, called precompiled procedures. Depending upon how often precompiled procedures are included, 20-90% of the operating costs of a Model 204 application can be saved. |
Error handling facilities | Trap and handle Model 204 errors in a single, centralized routine. Each subsystem can have one error procedure that is invoked each time a Model 204 error occurs during that subsystem's processing. Model 204 provides facilities for determining the type of error that caused the error procedure to be invoked. |
Security facilities | Allow or restrict access to the subsystem. |
Parallel Query Option/204 compatibility | Can be defined to allow referral to remote files and scattered groups. |
Subsystem definition
The characteristics and components of a subsystem are defined to Model 204 by the system manager during a process called subsystem definition. The defined options and components are stored in the system file CCASYS. Once a subsystem has been defined, all Dictionary users can display the options and components through Dictionary. For more information about:
- Displaying a subsystem definition, see Overview of the Subsystem Management facility.
- Defining subsystems that refer to remote files and scattered groups, see PQO client and service subsystems.
Subsystem design components
During subsystem definition, the components listed below can be defined. These components impact various aspects of subsystem design. The following table summarizes the required component designations.
Component | Subsystem design requires designation of... |
---|---|
Command line global variable | (Optional) parameter global variable. The parameter global variable allows any parameters specified by a user during a subsystem login to be stored in this variable and retained when control is transferred to another subsystem. |
Communication global variable and exit value | Communication global variable and exit value. The communication global variable is used to transfer control from one procedure to another. The exit value is used to leave the subsystem. Optionally, a reserved global variable is available for transferring control between subsystems. |
Error global variable | Error global variable. If an error occurs while the subsystem is executing, a three-character error code is stored in this variable. This code can then be used by an error procedure to determine the action to be taken by the subsystem. |
Prefix designations | Two prefixes for procedure names. These prefixes allow Model 204 to determine whether a procedure can be saved in its compiled form for later evaluation. |
Processing components | Specific procedures for types of special processing. These procedures allow Model 204 to determine the flow of control within a subsystem. |
Command line global variable
A command line global variable allows you to store any parameters specified by an end user during a subsystem login and retain this information when control is transferred to another subsystem. The designation of a command line global variable is optional.
Using the command line global variable
The command line global variable is used in the following manner:
- A user logs into a subsystem by entering the subsystem name followed by the parameter information. The total length of the parameter information entered by the user can consist of as many as 255 characters. (The portion of the command line reserved for parameter information is discarded if no parameter information is defined.)
- The portion of the input following the subsystem name is placed into a command line global variable, which then is available to the application program. For example:
PAYROLL parameter1 parameter2
is the command that logs the current user into the subsystem named PAYROLL. The string parameter1 parameter2 is the subsystem command line and is made available to the application via a global variable. If CMDL is the name assigned to the command line global variable, the following statements:
BEGIN %CMD.LINE = $GETG('CMDL') %FIRST.PARM = $Substr(%CMD.LINE,1,$INDEX(%CMD.LINE,' ')-1)
would assign the contents of the command line used to enter the subsystem to %CMD.LINE and the first parameter of the line to %FIRST.PARM.
Transferring control to another subsystem
The contents of command line global variables are not deleted when control is transferred from one subsystem to another. A request can set the contents of the command line global variable of the destination subsystem before transferring control to that subsystem. The effect is the same as if the parameters were entered on the user's terminal.
Impact of the UTABLE command
The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem.
Communication global variable
Transferring control
A communication global variable lets you transfer control at two levels:
From... | Control is transferred by a... |
---|---|
One procedure to another | User-designated global variable. |
One subsystem to another | Reserved global variable named XFER. |
Transferring control between procedures
Subsystem procedures pass control from one to another through the use of the communication global variable. The communication global variable name for a subsystem is specified in the subsystem definition. Each subsystem procedure must set the value of the communication global variable to the name of the next procedure to be executed.
Example
For example, the subsystem AUTOS has procedures PRE-MAIN.MENU and PRE-RPT.PGM and the communication global variable NEXT. PRE-MAIN.MENU is currently executing and wants to pass control to PRE-RPT.PGM. Before PRE-MAIN.MENU finishes, the function $SETG is used to store procedure name PRE-RPT.PGM in NEXT:
IF $SETG('NEXT','PRE-RPT.PGM') THEN ...
After PRE-MAIN.MENU ends, Model 204 examines NEXT and begins executing PRE-RPT.PGM.
Subsystem exit value
A subsystem is exited by setting the value of the communication global variable to the subsystem exit value. The exit value for the communication global variable is also specified in the subsystem definition.
For the AUTOS subsystem used in the preceding example, the exit value of the communication global variable is defined as EXIT. To disconnect the user from the AUTOS subsystem after procedure PRE-RPT.PGM is finished executing, PRE-RPT.PGM assigns the exit value, EXIT, to the communication global variable, NEXT.
IF $SETG('NEXT','EXIT') THEN . . .
Transferring control between subsystems
One subsystem can invoke another subsystem by transferring control from itself to another subsystem. To accomplish this, you must perform these steps:
- Set the communication global variable to the value XFER.
- Set the global variable XFER to the name of the subsystem to which control is being passed.
When the current procedure finishes executing, Model 204 disconnects the user from the old subsystem, transfers control to the new subsystem, and invokes the login procedure for the new subsystem.
Design considerations
You should consider the following factors when coding logic for transferring control between two subsystems:
- The transfer always invokes the login procedure of the subsystem receiving control. For more information on the login procedure, refer to the discussion Subsystem processing flow.
- The destination subsystem must be active. The $SUBSYS function should be used to determine if the subsystem to which control is being transferred is active; refer to the discussion on Subsystem procedure control functions. If the destination subsystem does not use the automatic start option, (see Operating options), the subsystem must be started before control is passed.
- The destination subsystem should not reset LGTBL if any parameters are passed in global variables.
- To return to the original subsystem, a global variable must be set to the name of the original subsystem. The communication global variable and the XFER global variable can then be used with the global variable that stores the subsystem name to return control to the original subsystem.
- The destination subsystem can return control to the procedure that the user was in when the user transferred. To do this, the subsystem must save the name of the procedure in a global variable. In addition, the login procedure must contain logic to return control to the procedure that the user was in.
- If the transferring subsystem is in test mode (see Security options), the transferring subsystem stops after it passes control. The destination subsystem is not placed in test mode.
Example
The following request in procedure PRE-SUB.MENU provides an example of subsystem transfer code. CREDIT and AUTOS are two defined subsystems with the automatic start option. (See Automatic start.) Subsystem CREDIT transfers control to AUTOS by setting NEXT (the communication global variable) to XFER and the global variable XFER to AUTOS. After the PRE-SUB.MENU procedure ends, the user is connected to AUTOS.
BEGIN . . . *SELECTION = 4 INDICATES CHOICE OF AUTOS SUBSYSTEM * SEL.AUTOS: IF %CREDITMENU:SELECTION = 4 AND - $SUBSYS('AUTOS') =1 THEN IF $SETG('XFER','AUTOS') OR - $SETG('NEXT','XFER') OR - $SETG('SUBFROM','CREDIT') OR - $SETG('PROCFROM','PRE-SUB.MENU') THEN PRINT 'GLOBAL TABLE FULL' END IF JUMP TO GET.NEXT . . .
Coding considerations
- Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.
- Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.
- To exit the subsystem, the communication global variable must be set to the exit value. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used.
Error global variable
The name of the error global variable must be specified in the subsystem definition. Whenever an error is detected that is not trapped by an ON unit, Model 204 automatically sets the subsystem's error global variable to a value which indicates the type of error that occurred.
Error code values
The "Error global variable values and reasons" table lists the error global variable values and their corresponding causes. Correct the cause of the error, and/or change your error procedure as discussed in Error procedures.
Error code | Reason |
---|---|
ATN | User pressed attention |
BUG | Evaluation errors |
CAN | Request evaluation canceled due to invalid terminal I/O in error procedure after BUMP or inactive thread time out. |
CNT | Counting errors |
FIL - BROKEN | Referenced file is not initialized, full, or physically inconsistent. Check the audit trail to determine the condition of the file. |
FIL - NOT OPEN | Referenced file not open |
GRP - FTBL | FTBL too small |
GRP - NOT OPEN | Group not open |
GRP - TEMP FIELD | TEMP group field has wrong type (see Restrictions for temporary and ad hoc groups in precompiled procedures) |
GRP - TEMP MISMATCH | TEMP group has wrong type |
INCLUDE MAX | Maximum iterations value has been exceeded. |
HNG | Phone hung up, connection lost |
HRD | Hard restart |
REC | Record locking table filled up during the load of a precompiled request |
RFR | After several tries, an APSY failed to invoke a procedure, because the procedure is in the process of being refreshed. |
SFT | Soft restart |
TBL - FSCB | FSCB too small |
TBL - NTBL | NTBL too small |
TBL - QTBL | QTBL too small |
TBL - STBL | STBL too small |
TBL - VTBL | VTBL too small |
Error procedures
An error procedure must test for different error conditions. The resulting value stored in the error global variable helps the application programmer determine the type of error that occurred.
- For all error codes except ATN, the error procedure should avoid re-executing the procedure that caused the error; otherwise, the error recurs.
- In most cases, the error procedure should display an informational message and set the global communication variable to the exit value.
- If a HNG error code is indicated, all terminal I/O (such as PRINT, READ) is ignored.
- If a HNG, HRD, or SFT error code is indicated, no terminal I/O (such as PRINT or READ) should be attempted. Instead, send a message to the audit trail in an AUDIT statement that indicates the error code encountered.
Considerations for the communications global variable
The communications global variable is ignored and disconnect processing completed when one of the following conditions occurs:
- Error is a soft restart, a hard restart, or a phone hang-up condition.
If you attempt to set the communications global variable to the name of another procedure, the procedure is not executed.
- No error procedure is specified in the subsystem definition.
An example illustrating how a subsystem error procedure can test for different error conditions is provided in Error procedure.
Precompiled and non-precompiled procedures
You can use two types of procedures in a subsystem:
- Precompiled procedure
The first time a precompilable procedure is invoked after a subsystem starts, it is compiled and stored for re-use. Because the compiler phase is bypassed each subsequent time the procedure is invoked (except as noted below), precompilation saves both CPU and elapsed time. Exceptions include the following:
- The procedure is recompiled the first time it is invoked for each SCLASS. The new compilation is evaluated, then discarded. It does not replace the original stored compilation.
- Further recompilations might be required due to temporary group differences. See Recompiling precompiled procedures for more on this.
- Non-precompiled procedure
A non-precompiled procedure is compiled each time it is invoked.
All procedures, whether precompiled or not, are invoked using the communication global variable.
Defining prefixes
During subsystem definition, two prefixes must be defined. The first prefix identifies precompiled procedures; the second identifies non-precompiled procedures. All procedures that are included for the subsystem through the use of the communication global variable (such as the login and main processing procedures) must have names that begin with one of these prefixes.
Contents of subsystem procedures
Subsystem procedures can contain Model 204 commands, a request, multiple requests, continued requests, sections of User Language code (for example, subroutines), or any combination thereof. However, the form of the procedure affects whether the procedure can be precompiled and should be taken into account when the subsystem is designed. Restrictions for precompiled procedures are discussed in detail below.
Server I/O can be reduced by allowing users executing shared precompiled procedures to use a shared version of QTBL. See Resident Request feature for precompiled procedures.
Restrictions for precompiled procedures
Model 204 must ensure that all of the code compiled and saved for a request with the precompiled prefix is consistent for all loading users. To achieve consistency, Model 204 restricts the way in which certain features are used.
Note the following restrictions for precompiled procedures when designing subsystem procedures:
- Procedures must contain exactly one request. The last statement must be END or END MORE.
- Requests cannot start with MORE.
- Procedures that include multiple BEGIN/END blocks are not eligible for precompilation.
- Requests must not refer to files or permanent groups that are not mentioned in the subsystem definition.
- Precompiled procedures can contain the User Language INCLUDE statement. The included procedures must be from a subsystem file. Any code inserted as a result of an INCLUDE statement is subject to all the restrictions for precompiled procedures.
- If a precompiled procedure issues the INCLUDE command to compile and run a User Language request, the INCLUDE command is saved, not the compilation of the request that was included.
- Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.
- Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.
- Dummy string substitution does not take place when saving commands that contain dummy strings. Instead, when the saved commands are loaded and executed, the current value of the dummy string is used. For example, if you include the following command in a precompiled procedure, whatever is currently in the global COMMAND is executed.
?%COMMAND
- If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.
- Procedures in UNLOCKed members of a PROCFILE GROUP are not precompiled.
Restrictions for temporary and ad hoc groups in precompiled procedures
Precompiled requests can refer to temporary or ad hoc groups as long as the files making up the group are specified in the subsystem definition. A temporary group of the same name must have the same composition characteristics for all loading users, as described below. If this condition is not met, Model 204 sets the error global variable to GRP-TEMP MISMATCH (see Error global variable).
- The temporary group for all loading users must be the same type. Model 204 assigns a type, based on the following file conditions:
- Some files have record security.
- All files are sorted or all are hashed.
- The sort or hash key has the same name in all files.
- Fields of the same name in the temporary group must be of the same type. Each field referenced in a temporary group each time a precompiled procedure is invoked must be found in a file. If this condition is not met, Model 204 sets the error global variable to GRP-TEMP FIELD (see Error global variable).
Field definition attributes can change for fields in temporary groups between compile and loading time. The following changes are allowed:
- If the field is NON-CODED in any file at compile time, it can be CODED in all files at loading time.
- If the field is BINARY or FLOAT in any file at compile time, it can be STRING in all files at loading time.
- If the field is non-NUMERIC RANGE in any file at compile time, the field can be NUMERIC RANGE in all of the files at loading time.
Recompiling precompiled procedures
When designing applications which use precompiled procedures and temporary groups, be aware that temporary groups can cause Model 204 to recompile precompiled procedures under certain conditions.
Precompiled procedures are recompiled when the request references a temporary group and the:
- Compiling user's temporary group consists of files which are smaller than one or more of the files in the loading user's temporary group of the same name.
- Compiling user's temporary group has fewer files than the loading user's temporary group of the same name.
- Update and retrieve privileges do not match those of the compiling user's temporary group (of the same name).
If one user's temporary group contains one large file, and another user's temporary group contains a number of smaller files, it is possible that a precompiled procedure is recompiled every time it is invoked. To prevent constant recompiling when files are of different sizes, compile temporary groups originally with the largest files and the greatest number files you expect to be included in the temporary group.
If, despite precautions, Model 204 must discard and recompile a precompiled procedure, the loading user must have exclusive access to that procedure: no other user can be executing the procedure within the same subsystem. If another user is executing the procedure, the loading user recompiles a private copy of the procedure. Model 204 discards the private copy when execution has completed.
Procedure compilation and Parallel Query Option/204
When a non-precompiled procedure that references remote files is invoked, one or more remote nodes participate in the compilation and evaluation. When a precompiled procedure is invoked, Model 204 loads the procedure on each of the nodes that participated in the original compilation.
When a subsystem member becomes unavailable during evaluation, the appropriate ON unit is activated.
Errors which occur while loading a remote procedure produce error messages which have the prefix RMT in the global error variable.
Saving compilations
As part of the compilation process, a list of remote nodes referenced in the request is generated with the compiled code. When compilation is complete, the compilation is saved along with the list of nodes. Each remote node referenced in the request is sent a signal to save the compilation.
If for any reason a compilation cannot be saved by a server node, the entire save operation fails.
Loading saved compilations
At the client node, the saved remote node reference list is checked to see which nodes are loading the request. When the request is loaded on the client, a signal is transmitted to each referenced server node to load the compilation.
New and missing nodes
A temporary group can be changed so that a node is new (not previously referenced) or missing (referenced but no longer available). Temporary groups with new and missing nodes shows how new and missing nodes affect recompilations and saves.
If there are missing nodes... | If there are no missing nodes.... | |
---|---|---|
And there are new nodes... | Recompile the procedure, do not save | Recompile and save again |
And there are no new nodes... | Just load and evaluate | Just load and evaluate |
Recompiling saved requests
Saved requests are always recompiled if a new node is introduced into a temporary group. Recompilation can cause a noticeable delay in response time.
In addition, the following changes in the composition of a subgroup also force recompilation of a request. A subgroup is the group of files at a server node referenced as a part of a group.
Model 204 recompiles saved requests when:
- The number of files in the subgroup has increased (for example, if a user's request includes a file that was unavailable to the previous user)
- The maximum number of segments in a subgroup has increased
Subsystem procedures
Types of subsystem procedures
Subsystem development involves writing the collection of procedures that make up a subsystem. Subsystem procedures can be categorized as one of four types:
Procedure category | Performs... |
---|---|
Initialization | Specified operations each time the subsystem is initialized. |
Login | As the entry point for each user of the subsystem. |
Main processing | Specific tasks of the subsystem. |
Error | Error handling. |
Guidelines and restrictions
- Procedures should be small and modular.
- Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.
- Non-subsystem files can be opened and referenced only by non precompiled procedures.
- If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.
- A subsystem procedure cannot issue the CREATE command for a subsystem file.
- LXTBL and LFTBL cannot be reset from within a subsystem procedure.
- All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed. The default action for each type of message is listed in M204.1076.
If you do not wish the default action to be executed, statements to handle a situation that would invoke the message should be added to the procedure.
Initialization procedure
The initialization procedure stores instructions for tasks you need to perform each time the subsystem is initialized. An example of such a task is the initialization of a particular work file.
The initialization procedure is optional. If a subsystem uses an initialization procedure, the procedure name must be specified in the subsystem definition.
Login procedure
The login procedure performs the start up for each user of an application. Every time a user invokes the subsystem, Model 204 automatically includes the subsystem login procedure.
The login procedure name must be specified in the subsystem definition.
Typically, the login procedure is used to store current server table sizes in the global variable table for later reference, issue UTABLE commands to set compiler table sizes for the subsystem, and set the communication global variable to the name of the procedure that displays an initial menu.
Example
Here is a sample login procedure:
CLEARG BEGIN IF $SETG('NTBL',$VIEW('LNTBL')) OR - $SETG('VTBL',$VIEW('LVTBL')) OR - $SETG('QTBL',$VIEW('LQTBL')) OR - $SETG('STBL',$VIEW('LSTBL')) OR - $SETG('FSCB',$VIEW('LFSCB')) OR - $SETG('LECHO',$VIEW('LECHO')) OR - $SETG('NEXT','PRE-MAIN.MENU') THEN PRINT 'GTBL FULL' END IF END UTABLE LNTBL=450,LQTBL=2300,LVTBL=600,LSTBL=3300 UTABLE LFSCB=5000 RESET LECHO 0
Main processing procedures
Main processing procedures perform the specific tasks of the subsystem. There can be as few or as many main processing procedures as necessary for the subsystem to perform its tasks. Main processing procedures are not specified in the subsystem definition. However, each procedure must follow the procedure naming conventions and subsystem coding rules discussed on this page.
Example
Here is a sample procedure:
BEGIN MENU MAINMENU TITLE 'AUTO INSURANCE SYSTEM (MAIN MENU)' AT 10 BRIGHT MAX PFKEY 12 SKIP 5 LINES PROMPT 'MAINTENANCE' AT 10 BRIGHT SKIP 2 LINES PROMPT 'REPORTING' AT 10 BRIGHT SKIP 2 LINES PROMPT 'EXIT' AT 10 BRIGHT END MENU %NEXT = 'X' REPEAT WHILE %NEXT = 'X' READ MAINMENU IF %MAINMENU:SELECTION = '1' THEN %NEXT = 'PRE-MAINT.PGM' ELSEIF %MAINMENU:SELECTION = '2' THEN %NEXT = 'PRE-RPT.PGM' ELSE %NEXT = 'NON-FINISH' END IF END REPEAT CHK.GTAB: IF $SETG('NEXT',%NEXT) THEN AUDIT 'GLOBAL TABLE FULL - "NEXT"' END IF END
Error procedure
An error procedure, which is optional, performs error handling. This procedure is invoked when a condition occurs that cannot be trapped by the executing procedure (for example, a compiler error or an attention with no ON ATTENTION unit coded). An error procedure tests for different error conditions and determines the next procedure to execute, based on the error code value stored in the error global variable. Terminal I/O in a subsystem error procedure following a BUMP or inactive thread timeout results in cancellation of the procedure.
Example
The following error procedure assumes that the error global variable name is ERRCLASS, the communication global variable name is NEXT, and the exit value of the communication global variable is EXIT.
PROCEDURE SYS-ERROR BEGIN * * GET THE VALUE OF THE ERROR CLASS GLOBAL VARIABLE * GET.VALUE: %ERRORCODE = $GETG('ERRCLASS') * * IF THE USER HIT ATTENTION, INCLUDE THE MAIN MENU SCREEN * IF.ERROR: IF %ERRORCODE = 'ATN' THEN %NEXT = 'SYS-MAIN-MENU' * * IF PHONE WAS HUNG UP, OR ANY KIND OF RESTART, THEN AUDIT * MESSAGE AND EXIT. DO NOT ATTEMPT ANY TERMINAL I/O * SINCE USER IS NO LONGER CONNECTED. * ELSEIF %ERRORCODE = 'HNG' OR - %ERRORCODE = 'SFT' OR - %ERRORCODE = 'HRD' THEN AUDIT 'SUBSYSTEM ERROR CODE: ' - WITH %ERRORCODE %NEXT = 'EXIT' * * CHECK FOR BROKEN FILE * ELSEIF %ERRORCODE = 'FIL - BROKEN' THEN PRINT ' SUBSYSTEM FILE IS BROKEN' PRINT ' CONTACT YOUR FILE MANAGER ' %NEXT = 'EXIT' * * SOME UNACCOUNTABLE ERROR HAS OCCURRED, SET EXIT * ROUTINE, AND EXIT WITHOUT DOING ANY TERMINAL I/O. * ELSE AUDIT 'NOT ACCOUNTED FOR SUBSYSTEM ERROR CODE: ' - WITH %ERRORCODE %NEXT = 'EXIT' END IF IF.ERROR * * SET COMMUNICATIONS VARIABLE TO EXIT VALUE * COMM.VAR: IF $SETG('NEXT',%NEXT) THEN AUDIT 'GTBL full in SYS-ERROR trying to set NEXT to ' WITH %NEXT PRINT 'GTBL FULL' END IF END.REQUEST: * END END PROCEDURE
Security options
During subsystem definition, various options are specified for a subsystem. Security options determine subsystem command and file and group privileges assigned to a user.
You can also specify system operation options during subsystem definition. System operation options are discussed in the Operating options section. For a detailed discussion of subsystem definition options, refer to System requirements for Application Subsystems.
Status of subsystem
The status of the subsystem affects the type of subsystem security that is implemented. The subsystem can have one of three status settings:
Status setting | Allows access to... |
---|---|
Public | All users. All users who enter a public subsystem are assigned to the single subsystem user class and have the same set of privileges. |
Semipublic | All users but permits different privileges to be assigned for each user. In a semipublic subsystem, one subsystem user class can be defined as the default class for all users not specifically assigned to another subsystem user class. |
Private | Only to specified users. Using a private subsystem prevents any unauthorized entry into the subsystem. All users who are allowed access must be assigned to one of the defined user classes. Unlike a semipublic subsystem, a private subsystem has no default user class. |
User class
The set of privileges assigned to a user is based on the user's subsystem user class or SCLASS. The SCLASS is used by Model 204 to determine the privileges assigned for each file and group in the subsystem when files are opened for the user. File and group privileges must be specified in the subsystem definition because Model 204 bypasses OPENCTL parameter settings and file passwords when opening subsystem files and groups for each user. Whenever the user invokes the subsystem, he/she is assigned the file and group privileges of that subsystem user class.
The SCLASS also determines whether or not the user can issue any of the subsystem control commands listed below. If Model 204 discovers that the user does not have the correct privileges to issue a command, an error message is displayed.
Subsystem control commands | Directs Model 204 to... |
---|---|
DEBUG SUBSYSTEM | Establish a test environment for a multiuser version of the TEST command extension. The subsystem does not have to be stopped to issue the DEBUG command.
When a user enters a subsystem in TEST or DEBUG mode, the user's MSGCTL parameter setting is not changed. All error and informational messages that are not suppressed by the user's MSGCTL setting are displayed on the user's terminal. |
START SUBSYSTEM | Activate the subsystem and make it available for use. If the subsystem is inactive when the START command is issued, Model 204 opens all the subsystem files and includes the subsystem initialization procedure. |
STOP SUBSYSTEM | Stop the subsystem and make it unavailable for use. Once a subsystem is stopped and all users have exited, then all locking and storage resources held by the subsystem are released and all the subsystem files and groups are closed. |
TEST | Establish a single user test environment. The TEST command is extended to TEST DEBUG SUBSYSTEM. The subsystem must be stopped to enter TEST mode. |
Note: Several aspects of START SUBSYSTEM and STOP SUBSYSTEM processing are unique to distributed applications. For a discussion, see Subsystem command processing.
Processing of security violations
The application subsystem traps security violations that occur while a user is running in a subsystem. File read and update security violations, procedure security violations, and field level security violations are interpreted as compilation or evaluation errors in the error global variable. The audit trail messages produced when the error occurred can be examined in order to identify a compilation or evaluation error as a security violation.
Compiling procedures with a different SCLASS
In the following situation, Model 204 saves User 1's compilation:
- There are multiple SCLASSes for a subsystem.
- User 1 saves a procedure under SCLASS 1.
- User 2, under SCLASS 2, recompiles the procedure.
- User 2's global variables contain different information from User 1's so User 2 tries to open different files or groups than User 1.
However, User 2's compilation is not saved: User 2 receives an error message:
M204.0468: COMPILATION NOT SAVED - reason
Operating options
Operating options affect certain aspects of the overall behavior of a subsystem. Operating options are distinct from security options, which are discussed in Security options. Subsystem options are also discussed in System requirements for Application Subsystems.
The following table lists the operating options and what they determine.
Operating option | Determines whether... |
---|---|
Automatic start | Subsystem automatically starts for the first user entering the subsystem. |
Locking files and groups for subsystem use | Users from outside the subsystem can open and update subsystem files while the subsystem is active. |
Automatic login | Users are automatically logged into Model 204 upon entering a subsystem. |
Automatic logout | Users are automatically logged out of Model 204 upon exiting a subsystem. |
Automatic COMMIT | Any outstanding updates are committed automatically whenever a subsystem procedure ends and transfers control using the communications global variable. |
Message displays | Disconnect, informational, and error messages are displayed for subsystem users. |
File usage | Subsystem can run when one or more files used by the subsystem are unavailable for use. |
Automatic start
If the automatic start option is selected, Model 204 invokes subsystem initialization when the first user attempts to enter the subsystem. The subsystem can be used without a privileged user first issuing the START SUBSYSTEM command.
If the automatic start option is not selected, subsystem initialization occurs only when the START SUBSYSTEM command is issued. The subsystem is then available for use.
Locking files and groups for subsystem use
If the locking files and groups option is selected, Model 204 prevents users that are not running in the subsystem from opening any of the subsystem files or groups while the subsystem is active.
If the locking files and groups option is not selected, users from outside the subsystem can retrieve, modify, or delete records in a subsystem file while the subsystem is active.
Automatic login
If the automatic login option is selected, Model 204 logs on the user when the user enters a subsystem. The user is logged in using the subsystem name as the Model 204 user ID. If the user already has logged into Model 204 before entering the subsystem, Model 204 first closes all the user's files and logs out the user.
The LOGOUT operations that occur as a result of Automatic Login (both at subsystem Login and Disconnect) ignore the SYSOPT=8 (DISCONNECT on LOGOUT) option.
If the login option is not selected, the user's Model 204 user ID is used during subsystem processing.
Automatic logout
If the automatic logout option is selected, the user is logged out of Model 204 upon exiting the subsystem. This option is particularly useful when combined with the automatic disconnect feature of Model 204.
The START SUBSYSTEM command ignores the SYSOPT=8 option for the Automatic Logout subsystem.
If the automatic logout option is not selected, Model 204 logs the user out of the subsystem in one of three ways:
- If the user was previously logged into Model 204, Model 204 restores the user's original user ID and returns the user to the Model 204 command environment.
- If the user was not previously logged into Model 204, the user is logged out of Model 204.
- The SYSOPT=8 option causes the user to be disconnected from Model 204.
Automatic COMMIT
If the automatic COMMIT option is selected, Model 204 automatically issues a COMMIT statement for any outstanding updates whenever a subsystem procedure terminates and transfers control using the communication global variable. If the COMMIT option is not selected, the application must issue the COMMIT statement to commit any pending updates.
Commit exits
Note: This feature is available as of Model 204 release 7.8. It is licensed and purchased separately from Model 204.
A commit exit enables you to set up SOUL code to run at commit time, as in: "on commit run xxx".
When the user executes a commit (or an implied commit), the APSY specified by COMMITX is driven on a transactional daemon.
The APSY follows standard APSY rules. The commit exit is only driven once; that is, subsequent commits do not call the APSY. The commit exit is only driven for TBO transactions.
A commit/backout coded inside the commit exit commits/backs out the active transaction. Any new transaction within the exit causes a new update unit to begin.
COMMITX parameter
The commit exit runs within the APSY defined by the COMMITX parameter and uses normal APSY processing.
The new parameter COMMITX is settable from User 0's parameter line or by the system manager. It can be reset at any time by the system manager.
Setting/Resetting the parameter sends a DYRWT message to the issuer and requires a Yes or No response (unless set/reset by user0).
If COMMITX is specified, all APSY subsystems participate by default but any can be exempted.
Activating the commit exit APSY
- To activate the commit exit APSY, issue:
Reset COMMITX apsyname
where apsyname is the APSY where you are running the commit exit.
Enter
Yes
at the confirmation prompt. - To exempt any APSY subsystem:
- Pull up the SUBSYSMGMT Operational Parameters screen for that subsystem.
- At the 'Subsystem supports commit exit' item, enter
N
.
- To deactivate the commit exit APSY, issue:
Reset COMMITX
Enter
Yes
at the confirmation prompt.
Examples
The following are examples of login exits which print all changed records.
Example 1
b %d object xmldoc auto new %rec object xmldoc auto new %d:loadchangedrecords %f string len 8 %r float %c float initial(1) repeat %d:selectcount('//Record') times %f = %d:value('//Record[' %c ']/@file') %r = %d:value('//Record[' %c ']/@number') %c = %c + 1 %rec:loadfromrecord(FILE=%f,RECORDNUMBER=%r) %rec:print %rec = new end repeat if $SETG('NEXT','EXIT') then audit 'gtbl full' end if end
Example 2
b %d object xmldoc auto new %d:loadchangedrecords(fields=true) %d:print if $SETG('NEXT','EXIT') then audit 'gtbl full' end if end
Example 3
b %d object xmldoc auto new %recs object xmldoc auto new %n object xmlnode %d:loadchangedrecords %f string len 8 %r float %c float initial(1) %n = %recs:AddElement('ChangedRecords') repeat %d:selectcount('//Record') times %f = %d:value('//Record[' %c ']/@file') %r = %d:value('//Record[' %c ']/@number') %c = %c + 1 %n:loadfromrecord(FILE=%f,RECORDNUMBER=%r,HEADER=TRUE) end repeat %recs:print if $SETG('NEXT','EXIT') then audit 'gtbl full' end if end
There are new parameters for several of the methods (as demonstrated above):
LoadChangedRecords: Fields=boolean (default=false)
If true, each individual changed record is loaded into the XMLDOC similar to LoadFromRecord.
LoadFromRecord: File=name RecordNumber=number
LoadFrom Record must normally be issued within a FOR record context. However, if both of these name required parameters are specified, the LoadFromRecord statement need not be within a FOR record context.
If either of these name required parameters is specified from within a FOR record context, an error message will be issued: ERROR 1081: %C inside record loop: Recordnumber/File parameters not allowed
LoadFromRecord: Header=Boolean (default=false)
If true, the header line of the method will be included for each item. This may be useful when LoadFromRecord is issued in order to load an XMLNODE.
The header will separate each record and designate the file and record number.
Error handling
Current behavior without commit exits
Without commit exits, an APSY does not commit automatically unless AUTOCOMMIT=Y is specified in the APSY definition.
- If a transactional daemon is created: Commit/backout must be explicitly specified within a daemon in order to effect the master’s transaction. Implicit commit on the daemon is never done. Normal end of the daemon does not affect the master. If the daemon procedure is cancelled, the master transaction is backed out. If the daemon procedure is abended, the master transaction is backed out and the APSY error proc is run on the master.
- If a non-transactional daemon is created: The master transaction is unaffected by the daemon. Both implicit and explicit commit affect the daemon transaction only. If the daemon procedure is cancelled, only the daemon transaction is backed out. If the daemon procedure is abended, both the daemon and master transaction are backed out and the APSY error proc is run on the master.
Each time that an APSY loads a new procedure, the various KSERRC flags are always cleared. So when an error procedure is called, the error flags are always zero.
With commit exits
With the commit exits feature, the commit exit essentially runs as a transactional daemon with the original user being a pseudo master. Lower level daemons follow normal daemon behavior.
If a commit exit is running, and the APSY fails, the APSY error exit is scheduled to run. If the APSY error exit exists, the original transaction unit will be unaffected, unless the exit specifically designates a commit/backout. If there is no APSY error exit, the original transaction unit is aborted with ERROR 2971: Action disabled by commit exit
and the user is restarted.
Message displays
Model 204 provides these message display options for subsystem users:
- Disconnect message display
- Model 204 informational message display
- Model 204 error message display
When a message display option is selected, messages of that type are displayed on the user's terminal. If a message display option is not selected, all messages of that type are not displayed on the user's terminal. Note that if the display of any Model 204 type message is suppressed, messages for the corresponding type are not displayed on the user's terminal, but are written to the audit trail file (CCAAUDIT).
Typically, subsystem applications are written so that all messages displayed on the user's terminal are produced by the subsystem and Model 204 messages are suppressed.
File usage
Mandatory vs. optional members
Files and permanent groups contained within the subsystem definition can be designated as mandatory (the default) or optional members of the subsystem:
- Mandatory members
Mandatory files or groups are automatically opened by Model 204 when a user logs into a subsystem and automatically closed when the user leaves the subsystem. Subsystem requests can assume that all mandatory files are open and that they are physically consistent. The user's file privileges are those defined in the subsystem definition for the current user's SCLASS. The opening of a mandatory member cannot be prevented by the subsystem administrator with the STOP FILE command when the subsystem is active. A mandatory member cannot be accessed by another copy of Model 204 until the entire subsystem is stopped.
If a subsystem procedure issues an OPEN or CLOSE command for a mandatory member, the command is ignored by Model 204 and the user's current privileges are not changed.
- Optional members
Optional files or groups provide the ability for a file or group to be stopped by a subsystem administrator (using the STOP FILE command) without stopping the entire subsystem. If a member is defined as optional, it is not automatically opened during the subsystem login. It must be opened by the application by using an OPEN/OPENC statement or command. The file privileges assigned are those specified in the subsystem definition for the current user's SCLASS. The member is closed (for that user only) when the user leaves the subsystem if a CLOSE command has not been issued.
When an optional member is not in use, it can be processed by another copy of Model 204.
Requests that reference mandatory or optional members can be precompiled. Files not contained in the subsystem definition can be opened and referenced within a subsystem application, but the requests that reference those files cannot be precompiled.
Automatic vs. manual members
Subsystem files and permanent group members can also be designated automatic or manual:
- An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem.
- A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command.
Mandatory files cannot be designated manual. Optional files can be designated either automatic or manual.
Permanent vs. temporary groups in subsystem definitions
The GROUP parameter of the subsystem definition applies only to permanent groups. Temporary group names cannot be used. To include temporary group members in a subsystem definition, and thus to enable their use in precompiled code, the members of the temporary group should be individually specified in the subsystem definition.
Summary of file definition options
Subsystem file definition options summarizes the subsystem file definition options.
Subsystem definition option |
Automatic
open and close? |
Pre-compiled code? |
Start/stop file command allowed? |
File privileges assigned |
---|---|---|---|---|
Mandatory | Must be automatic | Yes | No | SCLASS |
Optional | Can be automatic or manual | Yes | Yes | SCLASS |
None | Cannot be automatic | No | Yes | File Password |
Subsystem processing flow
To design a subsystem, you must be familiar with the flow of control that occurs during subsystem processing. Subsystem processing typically involves the following phases:
Type of processing | During this processing... |
---|---|
Initialization | Subsystem is started and an optional initialization procedure is included. |
Login | User is logged into the subsystem; the user's privileges are determined by the subsystem definition. The appropriate required files and groups are opened for access. |
Driver | Procedures that make up the main body of the application are included. |
Disconnect | All files and groups are closed for the user, who is then logged out of the subsystem. |
Error | An optional error procedure is included. The type of error that occurred is available to the error procedure. For many types of errors, the error procedure can resume normal driver processing. |
Initialization processing
Initialization processing is invoked when the subsystem is started. A subsystem is started by the START SUBSYSTEM command, or, if the start option is indicated in the subsystem definition, when the first user enters the subsystem.
During subsystem initialization, Model 204 finds the subsystem definition and opens only required subsystem files and groups. If a required file or group cannot be opened, the subsystem initialization procedure terminates and the user is returned to command level.
One of the subsystem components opened during initialization is the procedure file (or group, if a multiple-procedure group has been specified). The procedure file or group must contain all of the subsystem procedures that are included by the subsystem through the communication global variable. Model 204 scans the subsystem procedure file or group for all procedures whose names begin with either of the subsystem procedure prefixes.
The subsystem initialization procedure is included at this time. This is the only time during subsystem processing that the initialization procedure is executed.
If no error occurs, Model 204 adds the subsystem name to the list of active subsystems. At this point, the subsystem is initialized and ready for use.
Login processing
Login processing is invoked when a user enters a subsystem. If the automatic login option is indicated in the subsystem definition, Model 204 logs on the user using the subsystem name as the user ID. If the automatic login option is not indicated, the user's Model 204 user ID remains in use.
Model 204 next finds the user's subsystem user class definition in CCASYS and opens only the required subsystem files and groups with the privileges that are found for that user class. The MSGCTL parameter automatically is set for the user according to the subsystem definition.
Model 204 sets the communication global variable to the name of subsystem login procedure and proceeds into driver processing.
Driver processing
Model 204 determines which procedure to include next by examining the value of the communication global variable. The procedure name must be one of the names located by the scan of the procedure file during subsystem initialization.
If either the global variable or the procedure name cannot be found, the subsystem's error procedure is included. If an error procedure is not specified in the subsystem definition, the user is disconnected from the subsystem.
If the procedure name is found, Model 204 determines which prefix begins the procedure name. Processing then occurs as follows:
- If the procedure name begins with the non-precompiled prefix, Model 204 includes the procedure for compilation and evaluation.
- If the procedure name begins with the precompiled prefix, Model 204 verifies whether the procedure was compiled previously with the set of privileges defined by the user's subsystem user class.
Once the compilation status of the procedure is determined, processing is as follows:
- If the procedure was not previously compiled successfully for the set of privileges defined by the user's subsystem user class, Model 204 includes the procedure for compilation and evaluation. If compilation is successful and no previous compilation was saved for the procedure, the contents of the compiler tables are saved in the system file CCATEMP.
- If the procedure was previously compiled successfully for the user's privilege set, Model 204 loads the contents of the compiler tables from CCATEMP and evaluates the request.
Model 204 repeats driver processing until the value of the communication global variable is set to the exit value specified in the subsystem definition. When the communication global variable is set to the exit value, Model 204 proceeds into disconnect processing.
Disconnect processing
Disconnect processing is invoked when the subsystem application sets the communication variable to the exit value, when an error occurs with no subsystem error procedure, or when a subsystem user is restarted by Model 204. During disconnect processing, Model 204 closes all required subsystem files and groups for the user, as well as any optional files and groups that have not been closed by the application.
Depending upon whether the automatic logout option is indicated, the user is then either logged out of Model 204 or returned to the Model 204 command environment.
Error processing
Error processing is invoked whenever a Model 204 error occurs that cannot be handled by the procedure being executed at the time. When an error is detected, Model 204 sets the value of the error global variable.
If the subsystem has a defined error procedure, the error procedure is included at this time. If the subsystem does not have a defined error procedure, Model 204 proceeds into disconnect processing.
If the error trapped by the subsystem is a soft restart, a hard restart, or a terminal disconnect condition, the error procedure is invoked. The communication global variable is ignored when the error procedure completes and Model 204 proceeds with subsystem disconnect processing.
Parallel Query Option/204 (PQO) considerations
This section introduces several terms and concepts which are unique to subsystems that reference remote files and scattered groups. These concepts, and related design considerations, are discussed in greater detail in PQO: Scattered APSY subsystems.
Remote file access
Parallel Query Option/204 provides access to remote files under the Subsystem Management facility by allowing the system manager to define client and service subsystems:
- A client subsystem is the subsystem a user is running in when requesting access to remote data.
- A service subsystem is the subsystem on a server node that a client user's service thread is logged into.
A service subsystem definition is stored in the CCASYS file on each node that the client subsystem accesses. The name of a subsystem must be the same at each node. The location of the client node is included in the subsystem name to uniquely identify it to the server node.
Node availability
A server node can be available or unavailable to a client subsystem.
- A node is available if the service subsystem has been successfully started.
- If the service subsystem has not been started, it does not have a subsystem definition structure accessible to the client and is therefore unavailable.
A node can only be marked unavailable during start processing if there are mandatory members on a server node and the service subsystem cannot be started. If this happens, start processing also fails on the client node.
Client subsystems attempting to access service subsystems that are not started receive an error message from the server node.
A previously available node can become unavailable when:
- Resumption of communication fails after recovering from a system failure.
- A user attempts to log into the service subsystem by logging into the client subsystem, the service subsystem definition is not found, and at least one mandatory member resides on that node.
- A user attempts to open a file on a node where the user was not previously logged in.
The user is automatically logged into all associated service subsystems when entering a subsystem that contains remote files. If the service subsystem is unavailable on a node, the user cannot be logged in.
File and group availability
The members of a subsystem are files and permanent groups. With Parallel Query Option/204, members can be either automatic or manual:
- An automatic member is a subsystem group or file that is opened automatically when the subsystem is started or when a user enters the subsystem.
- A manual member is a group or file that must be opened explicitly by the OPEN or OPENC command.
Members can also be either mandatory or optional:
- A mandatory member must be open in order to access a subsystem. Mandatory members cannot be manual.
- An optional member is not required for subsystem access (start and login processing can succeed without it).
At any given time a member can be open or closed to a subsystem or to a user within a subsystem. The following sections explain the conditions under which the different kinds of members are accessible to APSY subsystems and their users.
Member availability to subsystems
Automatic members of subsystems are always opened by the START SUBSYSTEM command or by SUBSYSTEM LOGIN. At the end of START processing, each automatic member is open unless either the START or OPEN failed.
Manual members of subsystems are in the closed state at the completion of START SUBSYSTEM processing and must be explicitly opened by the user. Manual members become open to the subsystem if an OPEN operation succeeds. If OPEN fails due to node unavailability or for user-specific reasons (for example, if the user's line goes down) the member remains closed to the subsystem.
If a node becomes unavailable to a subsystem, all automatic subsystem members and all open manual subsystem members residing on the unavailable node are marked disabled.
If a STOP FILE/GROUP command is issued for a manual member on the client subsystem's node, the member is closed to the client subsystem when the last user closes it. If the member is located on the service subsystem node, the file is closed to the service subsystem when the STOP is complete or the last user closes the file.
Member availability to subsystem users
When a user enters a subsystem, automatic subsystem members are opened.
If a user LOGIN or OPEN operation fails for an optional member, the member is left closed for the user but remains available to the subsystem. If a mandatory member cannot be opened, the user is denied access to the subsystem.
If a user LOGIN or OPEN operation fails for an already open member, the member is left disabled for the user but remains open to the subsystem.
If an automatic mandatory member is closed to the subsystem, new users are not allowed to enter the subsystem.
Manual members of subsystems are closed for a user within a subsystem until the user issues an OPEN command or statement. In this case it does not matter whether the member is open or closed to the subsystem.
If compilation and/or loading of a request fails due to a communications failure, previously opened members on the failing node become disabled to the user.
A user can close optional members at any time by issuing the CLOSE command.
Enabling disabled subsystem files
In the event that a subsystem file or group is marked disabled, you can enable it (after correcting the problem) without having to bring the subsystem down. To do this, use the ENABLE SUBSYSTEM command:
Syntax
ENABLE SUBSYSTEM subsysname [FILE name AT location | GROUP name]
Where:
- subsysname is the name of the client subsystem
- location is the name of the remote node where the file is stored. Note that the location must be explicitly specified; you cannot reference local files with the ENABLE SUBSYSTEM command.
Intentionally disabling a subsystem file
You can make a subsystem file or group (or an entire subsystem, if a file is mandatory) temporarily inaccessible without having to bring the subsystem down, using the DISABLE SUBSYSTEM command:
DISABLE SUBSYSTEM subsysname [FILE name AT location | GROUP name]
When a file or group is intentionally disabled with the DISABLE SUBSYSTEM command, subsystem behavior is exactly the same as when a communications failure causes the disabling. This behavior is described in File and group availability.
Trust
As an alternative to the privilege settings normally available through the Subsystem Management facility, the system manager at a service node can control client subsystem access by creating a trust definition for the client subsystem. If a client subsystem is fully or partially trusted, the trust definition is sufficient for maintaining the relationship with the client; the system manager at the service node does not have to create and maintain a separate set of file and SCLASS definitions for the client subsystem.
For example, suppose a subsystem located on a node named DETROIT (the client node) includes in its definition files located on a node named CLEVELAND (the service node). Further, suppose the subsystem is fully or partially trusted by CLEVELAND. In this case, the file and SCLASS definitions are maintained only on the client node (DETROIT), and the service node (CLEVELAND) needs only to maintain the trust definition.
The four levels of trust available with Parallel Query Option/204 are:
- Full trust
Only the subsystem name and location appear on the service node's definition, which you create on the Subsystem Trust screen.
- Partial trust
Along with the subsystem name and location, you can specify maximum file privileges. In this case, the client subsystem is trusted, but the maximum file privileges and field level security levels specified on the Subsystem Trust screen cannot be exceeded.
- If a user requests file privileges that would exceed the maximum, the service node does not open the file to that user.
- If a user requests a field level security status that would exceed the maximum, Model 204 automatically resets the request to the allowed level (that is, the maximum) and opens the file to that user.
- Restricted trust
For a subsystem that has a restricted trust definition, you make no entries on the Subsystem Trust screen. A restricted trust definition is based solely on entries you make on these five screens:
- Subsystem Activity
- Subsystem File Use
- Operational Parameters
- Subsystem Classes
- Subsystem Class Users
The accessibility of service node files to a client subsystem is determined by the SCLASS, user, and file privileges that you specify on these screens.
- No trust
No subsystem service definition exists for the subsystem. The client subsystem cannot access any files on the service node as subsystem files. The files on the service node can, however, be accessed from within a client subsystem as individual, non-subsystem files if the following criteria are met:
- Parallel Query Option/204 is installed at both sites.
- Horizon is installed at both sites, and there are link, processgroup, and process definitions connecting the client node to the service node.
- For any given file, the value of the OPENCTL parameter allows remote access (X'02', X'04', or X'08').
See the Rocket Parallel Query Option/204 User's Guide for detailed information on creating and managing trust definitions.
Subsystem design considerations
This section presents coding considerations for subsystem procedures. Some of the guidelines listed below also appear in earlier sections. They are consolidated here for the convenience of the application developer.
Coding considerations
- Procedures should be small and modular.
- Procedures to which control is passed via the communication global variable must be stored in a designated procedure file. The procedure file is the default file for a subsystem application unless the default file is explicitly changed by a DEFAULT command or overridden by an IN clause.
- Each procedure must set the communication global variable to indicate the next procedure to be included. If this variable is not set, an error or loop occurs.
- The communication global variable must be set to the exit value in order to exit the subsystem. Server table sizes and other parameters should be reset to the values existing prior to entering the subsystem so that the user is returned to his/her normal operating environment. Parameter values are restored automatically when the automatic login option is used.
- Included procedures normally are included by using the INCLUDE command. Included procedures cannot be precompiled.
- Non-subsystem files can be opened and referenced only by non-precompiled procedures.
- Precompiled procedures cannot reference PERM groups that are not members of the same subsystem.
- Compiler table sizes must be the same each time a precompiled procedure is invoked. The UTABLE command should be used carefully.
- The contents of the command line global variable are not deleted by UTABLE commands which normally delete the contents of GTBL, as long as the UTABLE command is issued from within a subsystem.
- Distinct group numbers are assigned to optional groups at START SUBSYSTEM time. Those numbers cannot be used by non-subsystem members opened within the subsystem. Thus the NGROUP limit used for earlier releases might be exceeded during either START or OPEN processing inside the subsystem.
- To prevent you from having the wrong file or group privileges in a subsystem, Model 204 closes optional files and groups before entering a subsystem. In earlier releases, optional files and groups were only closed when you left the subsystem.
Users should be aware of the following conditions when coding applications to run under the Subsystem Management facility:
- Dummy strings (??, ?$, ?&) in precompiled procedures are resolved only during compilation for the first user.
- If a subsystem file is referenced by a precompiled procedure, no user can RESTORE or INITIALIZE the file, or RENAME, DELETE, or REDEFINE a field while the subsystem is active.
- A subsystem procedure cannot issue the CREATE command for a subsystem file.
- LXTBL and LFTBL cannot be reset from within a subsystem procedure.
- All DO YOU REALLY WANT TO messages are suppressed and the default action is assumed.
The default action for each type of message is listed in M204.1076.
If you do not wish the default action to be executed, you need to add a message handler routine to the procedure containing the statement that invokes the message.
Keeping track of the number of files referenced
To keep track of the files referenced in a subsystem procedure, which cannot exceed 6,043 files — a CCATEMP page, use the following formula:
NFILE + NRFILE + 1 (for CCAGRP) + 1 (for CCASYS)
Record locking considerations
Depending upon the subsystem definition, Model 204 might place a share lock on one or more subsystem procedure names or group names.
If the subsystem is defined with permanent groups, Model 204 locks the group names to ensure that the group definitions do not change while the subsystem is running. A share lock is maintained for each group while the subsystem is active.
If subsystem files are defined as unlocked
If the subsystem definition specifies that subsystem files are unlocked, Model 204 locks in share mode each of the subsystem procedures to ensure that the procedures do not change or move. This prevents any user from:
- Issuing the DELETE PROCEDURE command
- Issuing the RENAME PROCEDURE command
- Updating the procedure while the subsystem is active.
Subsystem procedure control functions
The User Language functions, $Sclass and $Subsys can be useful in determining subsystem program control.
$Sclass function
The $Sclass function returns the Sclass name of the current user. $Sclass is useful when the transfer of control is dependent upon a user's privileges. For example:
BRANCH: JUMP TO (ADD.REC, VIEW.REC, UPD.REC) - %MAIN.MENU:SELECTION . . . UPD.REC: IF $sclass = 'READ' THEN IF $SETG('NEXT','PRE-RPT.PGM') THEN PRINT 'GLOBAL TABLE FULL' END IF ELSEIF $sclass = 'UPDATE' THEN IF $setg('NEXT','PRE-MAINT.PGM') THEN PRINT 'GLOBAL TABLE FULL' END IF . . .
$Subsys function
The $Subsys function returns a numeric value indicating the status of a subsystem, or the name of the current subsystem (if no argument is specified). $Subsys often is used to determine whether a subsystem is active before a transfer is attempted.
Subsystem development tools
This section describes three Model 204 features that are useful in developing, testing and debugging subsystem procedures:
- The DEBUG and TEST commands, which assist subsystem debugging by allowing you to display the global communications variable and specify the next procedure to be INCLUDEd.
- Multiple procedure file groups, which allow users to change procedures without stopping the subsystem or interfering with other users.
- The Cross-Reference facility, which produces reports on the variable names, global dummy strings, and other language elements used in a specified set of User Language procedures.
Debugging and testing facilities
The Model 204 DEBUG and TEST SUBSYSTEM commands assist you in debugging subsystem code while it is being developed. Both commands display the value of the communication global variable, prompt you for changes, and display since-last statistics.
DEBUG differs from TEST SUBSYSTEM in the following ways:
- DEBUG can be executed by more than one user in the same subsystem at the same time; TEST SUBSYSTEM can only be executed by a single user.
- To execute TEST SUBSYSTEM, the user must stop the subsystem, which will be restarted in single user mode as a result of issuing the TEST command. To execute DEBUG, the user does not have to stop the subsystem. The DEBUG command can be issued for any subsystem that has been started, or for any subsystem that has the AUTOSTART feature.
- Since-last statistics are provided automatically with DEBUG; they are optional with TEST.
In general, the DEBUG command is more convenient for subsystem developers in a multiuser environment.
To execute the DEBUG command, the user must be named to an SCLASS which has been granted either the TEST or DEBUG privilege. The DEBUG privilege does not entitle the user to execute the TEST command.
Syntax
The format of the DEBUG command is:
DEBUG SUBSYSTEM subsystemname [parameters]
The extended format of the TEST command is:
TEST [DEBUG] [STATS] [SUBSYSTEM] subsystemname parameters
Where:
- DEBUG specifies that the communication global variable is displayed on the user's terminal before the next procedure is included. The user then has the option of specifying a different procedure to be included next. If the user presses ENTER without specifying a different procedure, the procedure whose name is currently displayed is included next.
- STATS specifies that since-last statistics are displayed on the user's terminal after each procedure is evaluated. Since-last statistics are described in User since-last statistics.
- SUBSYSTEM specifies that the word following the keyword is the name of a subsystem and that parameters follow the subsystem name. This keyword can be used to eliminate confusion when DEBUG or STATS is the name of a subsystem or subsystem parameter.
- parameters specifies the parameters to be stored in the command line global variable. The parameter information can be as many as 255 characters in length.
Multiple procedure files
If PROCFILE=*
is specified when a group is created, then several files in a group can contain procedures. When the INCLUDE command is executed in the context of a multiple procedure file group, files are searched, left to right, in the order they were defined in the original CREATE GROUP command.
Multiple procedure file groups make it possible to change subsystem procedures without having to stop the subsystem. This is accomplished by setting GROUP to Y
for the subsystem's procedure file in the subsystem definition, and by specifying a number value for Procs NUMLK that is less than the number of files in the group. The application subsystem locks the procedures in the last (or rightmost) NUMLK number of files, as determined by the right-to-left order they were specified in the CREATE GROUP command that defined the procedure group. For an example, see Subsystem File Use screen.
The multiple procedure file option also allows different users to make changes to procedures in the same subsystem without interfering with each other. The procedure group specified in the subsystem definition must have a corresponding CREATE PERM GROUP definition. However, any individual user can create or open a temporary group with the same name as the subsystem's permanent procedure group. If a user has such a temporary group open and enters a subsystem, the subsystem uses the temporary group instead of the subsystem's permanent group.
The following restrictions apply to the use of temporary groups to store subsystem procedure files:
- The user's SCLASS must have the TEST or DEBUG privilege.
- The last n files of the CREATE PERM GROUP command (where n is set by the
NUMLK
parameter) must correspond exactly to the last n files of the CREATE TEMP GROUP command.
Cross-Reference facility
The Cross-Reference facility is a Dictionary facility that can be invoked from both the Dictionary Main Menu and Model 204 command level. It produces reports for users who develop and maintain Model 204 User Language procedures.
The output reports show the line numbers where language elements such as labels, functions, images and variable names occur in a specified set of procedures. Elements within subroutines and nested INCLUDEs can also be cross-referenced.
The Cross-Reference Report is produced in batch mode (by a batch job in OS and DOS, by a service machine in CMS). Prior to submitting a cross-reference job, the user can specify:
- A set of procedures in a procedure file or group
- A set of language elements to be cross referenced
- Substitute values for User Language global dummy strings
- Job-related parameters such as output destination and lines per page
The Cross-Reference facility also includes Preview and Browse functions, which inform the user about the procedures selected for processing.
For a complete description of the Cross-Reference facility, refer to the Dictionary/204 topics.