Building Distributed
Applications
Using the Progress AppServer


Remote Procedure Code Examples

This section presents Progress AppServer-related code examples. The first example presents the code for a non-persistent procedure. The remaining two examples show two different ways to write code for the same remote persistent procedure.

Example 1: Remote Non-Persistent Procedure Example

This example shows how to run a remote, non-persistent procedure, checkstk.p, on an AppServer identified as hAppSrv. The TRANSACTION DISTINCT option is used on the RUN statement to specify that the client application’s transaction is not propagated to hAppSrv. The two temporary table parameters that are defined, ttOrderLine and ttItem, are passed as INPUT and OUTPUT parameters, respectively, to the checkstk.p procedure.

DEFINE VARIABLE hAppSrv AS HANDLE  NO-UNDO.
DEFINE VARIABLE ret     AS LOGICAL NO-UNDO.

DEFINE TEMP-TABLE ttOrderLine LIKE Order-Line.
DEFINE TEMP-TABLE ttItem      LIKE Item.

CREATE SERVER hAppSrv.
ret = hAppSrv:CONNECT("-AppService inventory -S 5162 -H zeus", 
                    "SMITH", "STARSHIP").
IF NOT ret THEN
  RETURN ERROR "Failed to connect to AppServer".
IF ERROR-STATUS:ERROR THEN
  RETURN ERROR RETURN-VALUE.

.
.

RUN checkstk.p ON hAppSrv TRANSACTION DISTINCT
  (INPUT Customer.Cust-Num,
   INPUT TABLE ttOrderLine,
   OUTPUT TABLE ttItem) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
  ret = hAppSrv:DISCONNECT().
  RETURN ERROR RETURN-VALUE.
END.

.
.

ret = hAppSrv:DISCONNECT().
DELETE OBJECT hAppSrv. 

When the RUN statement is executed, a remote procedure request to run checkstk.p is sent to the AppServer instance that is connected via the hAppSrv server handle. Once the RUN statement is completed, this code checks to see if checkstk.p completed with an ERROR condition as would occur by executing the RETURN ERROR statement. If checkstk.p did execute the RETURN ERROR statement, then this code also returns with an ERROR condition. By using the RETURN-VALUE function, the code also returns the value returned by checkstk.p.

Example 2: Remote Persistent Procedure Example

This code example shows how to instantiate a remote persistent procedure, order.p, on an AppServer.

DEFINE VARIABLE hAppSrv AS HANDLE  NO-UNDO.
DEFINE VARIABLE hOrder  AS HANDLE  NO-UNDO.
DEFINE VARIABLE iOrderNum AS LIKE Order.Order-Num NO-UNDO.
DEFINE VARIABLE ret     AS LOGICAL NO-UNDO.

DEFINE TEMP-TABLE ttOrder     LIKE Order.
DEFINE TEMP-TABLE ttOrderLine LIKE Order-Line.

CREATE SERVER hAppSrv.
ret = hAppSrv:CONNECT("-AppService inventory -S 5162 -H zeus", 
                    "SMITH", "STARSHIP").
IF NOT ret THEN
  RETURN ERROR "Failed to connect to AppServer".
IF ERROR-STATUS:ERROR THEN
  RETURN ERROR RETURN-VALUE.

.

.
RUN order.p ON hAppSrv TRANSACTION DISTINCT
  PERSISTENT SET hOrder.

RUN GetExistingOrder IN hOrder
  (INPUT iOrderNum,
   OUTPUT TABLE ttOrder,
   OUTPUT TABLE ttOrderLine) NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
  ret = hAppSrv:DISCONNECT().
  RETURN ERROR RETURN-VALUE.
END.

.
.

ret = hAppSrv:DISCONNECT().
DELETE OBJECT hAppSrv. 

When the RUN statement for order.p completes, a reference to the persistent procedure context is saved in handle hOrder. The SERVER attribute for hOrder contains a reference to the server handle hAppSrv. When the internal procedure GetExistingOrder is run for persistent procedure hOrder, Progress uses the value of hAppSrv to determine the AppServer instance where the persistent procedure is located.

Example 3: Remote Persistent Procedure Example Using the FUNCTION Statement

This example shows how a client application invokes a user-defined function, GetExistingOrder, that is implemented remotely on an AppServer. It is presented as an alternative way to code example 2. The FUNCTION GetFirstOrder statement in this example replaces the internal procedure GetExistingOrder referenced in example 2.

DEFINE VARIABLE hAppSrv AS HANDLE  NO-UNDO.
DEFINE VARIABLE hOrder  AS HANDLE  NO-UNDO.
DEFINE VARIABLE iCustNum AS LIKE Order.Order-Num NO-UNDO.
DEFINE VARIABLE ret     AS LOGICAL NO-UNDO.

DEFINE TEMP-TABLE ttOrder     LIKE Order.
DEFINE TEMP-TABLE ttOrderLine LIKE Order-Line.
/* user-defined function GetFirstOrder */
FUNCTION GetFirtOrder RETURNS LOGICAL 
  (INPUT inpcustnum AS INTEGER, 
   OUTPUT TABLE ttorder, 
   OUTPUT TABLE ttorderLine) in hOrder. 


CREATE SERVER hAppSrv.
ret = hAppSrv:CONNECT("-AppService inventory -S 5162 -H zeus", 
                    "SMITH", "STARSHIP").
IF NOT ret THEN
  RETURN ERROR "Failed to connect to AppServer".
IF ERROR-STATUS:ERROR THEN
  RETURN ERROR RETURN-VALUE.

.
.

RUN order.p ON hAppSrv TRANSACTION DISTINCT
  PERSISTENT SET hOrder. 
IF NOT GetFirstOrder (INPUT iCustNum,OUTPUT TABLE ttorder, OUTPUT TABLE 
ttorderline) THEN DO:
  ret = hAppSrv:DISCONNECT().
  RETURN ERROR.
END.
.
.

ret = hAppSrv:DISCONNECT().
DELETE OBJECT hAppSrv. 

Like example 2, when the RUN statement for order.p completes, a reference to the persistent procedure context is saved in handle hOrder, and the SERVER attribute for hOrder contains a reference to the server handle hAppSrv. However, instead of running an internal procedure, it runs the user-defined function, GetFirstOrder.

For more information about creating user-defined functions, see the FUNCTION Statement section in the Progress Language Reference .

NOTE: If a client application exits without executing the DISCONNECT( ) method on the appropriate handles, Progress automatically disconnects the client from the AppServer. This automatic disconnection can also occur if the AppServer machine looses network connectivity with the client application. This can happen, for example, if the is a network failure.


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095