Technique #4: grouping multiple server calls with Appeon Labels

Part of this section, mainly including introduction to Appeon Labels and the two examples, are quoted from an article titled Appeon Performance Tuning published in ISUG Journal - October 2011 Edition written by Yakov Werde.

Appeon deployment is a multiphase process. In the first phase PowerScript code is analyzed and converted into two categories of code (1) HTML and JavaScript that interact with the Browser and (2) JavaScript that interacts with the Appeon ActiveX component. During this phase the deployment tool converts embedded SQL and DataWindow database centric code (retrieves and updates) into RPCs (remote procedure calls) that interact with Appeon components in the Application Server. The important fact to understand is that both the Appeon deployment and runtime engines distinguish between the different categories of code. Additionally, Appeon engineers, recognizing the importance of performance tuning RPC code, provided language constructs that allow an application developer to demarcate and group RPC code in ways that will allow the runtime engine to performance enhance browser/server communication. These performance enhancing language extensions are called Appeon Labels.[1]

Appeon PowerServer provides seven "Appeon Label" functions, which can be found in the appeon_nvo_db_update object in appeon_workaround.pbl (Although the PBL is named workarounds, it also contains many useful utility classes and methods). When you examine the code of these functions, you will find the code either looks like the same nested PowerScript you have already written (such as of_update( )), or has no implementation (such as of_startqueue( )). The fact is: Appeon Label functions serve as markers (hence, the name Label) to the deployment tool; and during the deployment process, Appeon generates efficient JavaScript ActiveX component call code that implements bandwidth saving functionality in the Web tier client. Therefore, Appeon Labels do not execute any code or modify how your PowerBuilder application works in a Client/Server environment. Rather, when used on the Web it will notify Appeon's runtime Web libraries to handle certain database operations differently than PowerBuilder with the aim of reducing the number of server calls.

Below are descriptions of the seven "Label" functions about how they handle the database operation. For details about the syntax and return values of these functions, please refer to the section called “Appeon Labels” in Workarounds & APIs Guide.

Table 5. Appeon Label functions

Label

Function

Description

Commit/Rollback Label

of_autocommitrollback

Notifies the Appeon Web application to automatically commit or roll back the first database operation statement after the label.

Commit Label

of_autocommit

Notifies the Appeon Web application to automatically commit the first database operation.

Rollback Label

of_autorollback

Notifies the Appeon Web application to automatically roll back the first database operation statement if the operation fails.

Queue Labels (Consists of Start Queue Label and Commit Queue Label)

of_startqueue

of_commitqueue

These two labels must be used in pairs. They notify the Appeon Web application not to commit database operations after the Start Queue Label until the Commit Queue Label is called (and unless an Appeon Immediate Call Label is called).

Immediate Call

of_imdcall

Notifies the Appeon Web application to immediately commit a database operation.

Update Label

of_update

It is used to reduce the number of interactions with the server caused by "interrelated updates". "Interrelated updates" usually occurs when the update result of one DataWindow determines whether another DataWindow should be updated.


Appeon Commit/Rollback Label

The Appeon Commit/Rollback Label (of_autocommitrollback) notifies Appeon to automatically commit or roll back operations to the database after updating or inserting.

For example:

gnv_appeonDbLabel.of_AutoCommitRollback()
update tab_a ......
if sqlca.sqlcode=0 then
	...... //code independent of database opertaions
	commit;
	......
else
	......
	rollback;
	......
endif

Appeon Commit Label

The Appeon Commit Label (of_autocommit) notifies Appeon to commit operations to database after updating and inserting.

For example:

gnv_appeonDbLabel.of_AutoCommit()
update tab_a ......

Appeon Queue Labels

There are two Appeon Queue Labels, the Start Queue Label (of_startqueue) and the Commit Queue Label (of_commitqueue). These two labels must be used in pairs. They notify Appeon not to commit database operations after the Start Queue Label until the Commit Queue Label is called (and unless an Appeon Immediate Call Label is called).

For example:

gnv_appeonDbLabel.of_StartQueue()
dw_1.retrieve(arg1,arg2)
dw_2.retrieve(arg3,arg2)
......
dw_3.retrieve(arg4)
gnv_appeonDbLabel.of_CommitQueue()

Appeon Immediate Call Label

The Appeon Immediate Call Label (of_imdcall) is used between the Appeon Start Queue Label and Appeon Commit Queue Label, when the return value of an operation that is called after the Appeon Start Queue Label determines the subsequent business logic, for example, the return value is used in a CASE or IF...THEN expression.

For example:

gnv_appeonDbLabel.of_StartQueue()
dw_1.retrieve()
gnv_appeonDbLabel.of_ImdCall()
select ... into :var_1,:var_2 ......

if var_1>0 then
	para = "ok"
else
	para = "false"
end if
dw_2.retrieve(para)
gnv_appeonDbLabel.of_CommitQueue()

Appeon Update Label

The Appeon Update Label (of_update) is used to reduce the number of interactions with the server caused by "interrelated updates". "Interrelated updates" usually occurs when the update result of one DataWindow determines whether another DataWindow should be updated.

The following example shows how Appeon uses the Update Label to reduce client-server interactions:

Example of interrelated updates:

if dw_1.Update()=1 then
    if dw_2.Update()=1 then
        commit;
        Messagebox("Success","Update success!")
    else
        rollback;
        Messagebox("Failure","Update all failure!")
    end if
else
    rollback;
    Messagebox("Failure","Update dw_1 failure!")
End if

Use the Appeon Update Label to rewrite the example:

l_rtn = gnv_appeonDb.of_Update(dw_1,dw_2)
if l_rtn=1 then
   Messagebox("Success","Update success!")
elseif l_rtn= -102 then
   Messagebox("Failure","Update all failure!")
Else
    Messagebox("Failure","Update dw_1 failure!")
End if

Script defined in the Update Label associated function, of_Update(dw_1,dw_2):

if dw_1.Update()=1 then
    if dw_2.Update()=1 then
        commit;
	  return 1
    else
        rollback;
	  return -102
    end if
else
rollback;
return -101
end if

The more database operations utilize Appeon Labels, the faster the performance will be. For PowerBuilder applications deployed to the Web with Appeon PowerServer, in many cases you will achieve acceptable runtime performance simply by utilizing this technique. The reason is that there are a number of features built into Appeon's infrastructure framework that automatically boost the performance of PowerBuilder applications over the Web. The performance boosting features are discussed in Automatic performance boosting.

Two Examples[1]

Now, let's see two situations where Appeon Labels reduce network traffic.

The first example illustrates performance enhancements when chaining DataWindow updates. Oftentimes, data contained in multiple data controls (datawindow, datastore or childdatawindow) must be grouped into a logical unit of work (LUW).

The following figure shows the pseudocode update algorithm. This code necessitates three browser to server round trips, one for each data control.

Figure 9. Nested Update Algorithm

Nested Update Algorithm

(Appeon groups all changed data into a single transmission). As you can see from the following figure, refactoring the code to use the Appeon Label of_update( ) method, reduces three round trips one. In the event of a failed update the method returns a result code indicating which update failed.

Figure 10. Call Appeon of_update method( )

Call Appeon of_update method( )

Sometimes a script has multiple embedded SQL statements grouped into a single LUW. Each SQL statement causes a browser to server round trip. The following figure illustrates one such (simplified) scenario.

Figure 11. Five Round Trips

Five Round Trips

In this case you can use the Appeon Labels of_startqueue( ) and of_endqueue( ) to demarcate logical statement groupings thereby reducing the number of server round trips. The code shown in the following figure reduces the number of server round trips by over 50% by dividing the SQL into two logical groups; the first group of statements acquires values necessary for statements in the second group.

Figure 12. Reduced to 2 Round Trips

Reduced to 2 Round Trips



[1] Quoted from an article titled Appeon Performance Tuning published in ISUG Journal - October 2011 Edition written by Yakov Werde.