ASNA WingsRPG™ Reference Manual |
The Runtime Lifecycle, LvlChk and LwtChk
The IBM i Display File Lifecycle
The IBM i Display File, as explored elsewhere is systematically created from a DDS. The DDS defines
formats, fields, subfiles and the like. Each format is
assigned a Format ID during *DSPF
generation. For example, if a simple DDS with two record formats (FM1 and FM2)
each of which has two fields (CREDIT
and DEBIT
for FM1
,
HOME
and CELL
for FM2
), was used to create a *DSPF
,
each record format would be assigned a
Format ID (FMTID1
and FMTID2
).
When an RPG program that uses the *DSPF
file (based on a workstation F-spec in the source code) is created,
the compiler embeds the Format IDs of the file into the program. At runtime, when the workstation file is opened,
the system checks the Format IDs embedded in the RPG program against the ones in the display file *DSPF object. If the
*DSPF
has been altered without recompiling the program, the Format
IDs won't match during the Format Level Check and a LVLCHK
exception
will be thrown, stopping the program.
One way around this safeguard is to override the level check using
CHGDSPF LVKCHK(*NO)
, however this opens your program up to
possibly corrupt data or other errors arising if incorrect or
mismatched instructions are present in the *DSPF
.
The Wings Display File Lifecycle
Wings is designed to work with RPG programs, and therefore it uses several parts of the
IBM i lifecycle. Specifically, the RPG program still checks
for Format IDs; however, in a Wings environment there is no *DSPF
available at runtime
to obtain the Format IDs of the display file from, instead
it is the responsibilty of the Wings Handler to provide these Format IDs.
Wings Display Files are .aspx pages: they are the equivalent of both
the DDS source where the display file is described and the *DSPF
object used at runtime to render the
display on a screen. In order for the Handler to interpret the data buffers presented to it by
the RPG program accurately, it must know the layout of the fields in the buffer; basically, it
must know the format of the record, and there must be a perfect match between the layout
according to the RPG program and Wings.
Wings stores the essence of the record format layout in a file
parallel to the .aspx with the extension of .wrf (Wings Record Format).
In a way, the .aspx and WRF pair, takes the place of the IBM i *DSPF
object at run time.
The WRF file contains an entry for each display record format with the ordered list of
the field's attributes composing the record.
The entry for each record format also contains its IBM i Format ID. This Format ID can
then be used by the Handler at open time to ensure that its mapping of the record layout
matches what was embedded by the RPG compiler when the program was created.
The WRF file is created by Wings when an initial .aspx page is Imported, and then it
gets updated everytime that the .aspx page is Exported back to the IBM i. In order to
guarantee that the mapping of the formats in the .aspx and the WRF definitions correspond
to each other, Wings embeds the timestamp (kept by Windows) of the last write operation
done to the .aspx page into the WRF.
This timestamp is known as the 'LastWrite Time' or LWT.
When the Handler receives a request to open a display file, it looks for the .aspx and WRF pair and checks that the .aspx LWT timestamp matches the one embeded in the WRF file.
If all goes smoothly, the RPG program runs against the .aspx page
just as if it were a perfectly formatted *DSPF
.
Mismatch Scenarios
If there is a mismatch in the LWTs, it means that the /aspx page was updated after the
last Export operation. It is possible, in the course of development or deployment, that the .aspx is
changed without Exporting it back to the IBM i. Naturally, this creates a failure-point,
as a WRF that doesn't match up with its .aspx could cause data
corruption or other errors. To prevent this, when performing an open
operation the Handler runs a
process called LwtCheck
(Last Write Time Check) and checks for the last time
the .aspx was saved and the LWT embedded in the WRF.
If they match up, the Handler concludes that all is well and moves
on.
However, the LWTs failing to match isn't, in itself, sufficient to throw an exception. Many alterations to the .aspx do not impact the formats and fields that concern the RPG program. For example, changing a background color or a border width. Therefore, if the LwtCheck fails, the Handler recomputes the the WRF from the .aspx: if no RPG-impacting changes have been made, the two WRFs will be identical (except the timestamp), and the open operation will be completed successfully.
In Debug mode, the WRF will also be automatically updated with the new LWT to prevent having to recompute it every time. Deployment environments (where the Handler may not have permission to update the WRF) merely pass the .aspx on while leaving the WRF unchanged.
If the recomputed WRF definition does not match the existing WRF, due to a signficant modification of the .aspx page, for example a field name or type change, or a reording of the fields in the format, a 'Level Check' exception is thrown and the open operation halts on the IBM i.
Published Websites
.aspx pages are not accessed directly by a browser, they are instead instructions that allow the ASPX engine to compile the page into HTML that a browser can read directly. It does this automatically the first time it is loaded by a web browser, creating a DLL (dynamic link library) reflecting the page or pages.
This one time compilation can cause a slowdown for the first user accessing the page. One way around this is to publish the .aspx as non-updatable. This means that ASPX creates all of the required DLLs well before the first use, consolidating all of the data into a single resource which cannot easily be edited. However, this process replaces the original .aspx page with a placeholder, an effectively blank document that points toward the DLL but contains almost nothing itself. This scenario interferes with Wings' default operations, as the LWT of the WRF (created on Export) will necessarily be different from the LWT on the .aspx placeholder (set on publish), and leaving Wings with no way of generating a new LWT because the .aspx page is empty. This will always cause a LwtCheck exception.
This scenario can be resolved by disabling LwtCheck; if the Handler doesn't check for the LWT, it will simply pass in the data from the WRF and follow the placeholder's pointer without issue. This can be set either within the WRF parameters on a page-by-page basis, or starting with Wings 6.2, globally in the web.config file.
Webpages can also be slowed down if there is a mismatch between the LWTs of the .aspx page and the WRF. The process of validating the .aspx, while not especially heavy, can cause a noticable delay (particularly if there are many pages with mismatched WRFs) as the Handler constructs a new WRF.
Therefore it's a best practice to always ensure that your .aspx pages and WRFs are in sync, but development teams must weigh the benefits of stability against the convenience of maintaining an updatable .aspx.
Disabling LwtCheck
Warning – The LwtChk
is there to prevent errors from slipping through,
like LvlChk
it should only be disabled after the the Display File has been tested. It should literally be the last thing done before deployment.
On a single Wings Display File:
The LwtChk
property in the WingsRecordFormat
element of the WRF must be set
to "*NO"
.
<WingsRecordFormat LvlChk="*YES" CcsId="37" LwtChk="*NO">
Globally
Starting with Wings 6.2, the Web.Config file's AppSettings AsnaDisplayFileLwtChk key's value can be set to "*NO".
<AppSettings> <add key="AsnaDisplayFileLwtChk" value="*NO"> </AppSettings>
See Also
Note – There are many ways to optimize the speed of .aspx pages. Some are discussed in the Optimizing Speed topic. Others are beyond the scope of this guide. We recommend the authoritative work by Dean Hume (www.deanhume.com), in his book Fast ASP.NET Websites