Building Distributed
Applications
Using the Progress AppServer
Running Remote Procedures
A remote procedure, whether it runs persistently or non-persistently, is scoped only to the AppServer session in which it runs. The order of execution for a remote procedure, relative to the client, depends on whether you execute it synchronously or asynchronously.
Synchronous Remote Procedures
If you run a remote procedure synchronously, the client application blocks until the remote procedure request completes and returns to the client. Execution then resumes in the client after the RUN statement that invoked the remote procedure.
Asynchronous Remote Procedures
If you run a remote procedure asynchronously, the client application continues execution immediately after the RUN statement that invokes the remote procedure completes. The remote procedure executes on the AppServer whenever the AppServer is available to execute it. You can then access the results of the remote request in an event procedure that executes in response to a PROCEDURE-COMPLETE event. The client handles the event in the context of a PROCESS EVENTS or other blocking I/O statement, similar to a user-interface event, and executes the event procedure like a user-interface trigger.
RUN Statement Options for Remote Procedures
You can use various options on the RUN statement to execute remote procedures:
- Run a synchronous external procedure using the ON [SERVER] handle-variable [TRANSACTION DISTINCT] option:
With a small change, this example can execute a remote procedure or a local procedure depending on whether hAppSrv contains a server handle value or the value of the SESSION system handle. Thus, with the same statement, you can run
order.p
remotely (with a server handle) or locally (with the SESSION handle), and determine the choice at run time:
- Run a remote persistent procedure using the ON SERVER and PERSISTENT SET handle-variable options:
A synchronous remote persistent procedure executes similarly to the same persistent procedure run locally. The AppServer session creates the context for the persistent procedure as it starts to execute, and that context persists after it returns until the end of the AppServer connection or until the persistent procedure is explicitly deleted (see the "Deleting Remote Persistent Procedures" section). Once a remote persistent procedure context is instantiated, you can execute any remote internal procedure or user-defined function that is defined within that remote persistent procedure.
The execution context for a remote persistent procedure is managed almost exclusively within the AppServer session where the persistent procedure is instantiated. However, the persistent procedure handle (hOrder in the example), as a proxy procedure handle, provides some additional access to the remote context from the client, allowing the client to delete the persistent procedure remotely. For more information on proxy persistent procedure handles, see the "Understanding Proxy Persistent Procedure Handles" section.
- Run a synchronous internal procedure or user-defined function using the IN handle-variable option:
In this example, both the GetOrders procedure and fnOrders user-defined function are defined in the remote persistent procedure specified by the proxy persistent procedure handle, hProc.
Note that running a synchronous remote internal procedure or invoking a remote user-defined function is syntactically identical to running it locally. Progress automatically determines the right AppServer connection and remote procedure or function to execute from the specified proxy persistent procedure handle.
- Pass INPUT, OUTPUT, and INPUT-OUTPUT variable or TEMP-TABLE parameters, but not BUFFER parameters.
- Run a procedure (internal or external) asynchronously using the ASYNCHRONOUS option:
This example asynchronously instantiates a remote persistent procedure,
order.p
, and when available, asynchronously calls the GetOrders remote internal procedure defined inorder.p
to return a TEMP-TABLE parameter with order information. While waiting for the persistent procedure,order.p
, to become available, the procedure does an unspecified amount of work. This part of the example is procedural, using the PROCESS EVENTS statement to handle the PROCEDURE-COMPLETE event each time through the loop. The status of the request is checked by testing the COMPLETE attribute of the asynchronous request handle (hAsync).After the example runs GetOrders asynchronously, the example blocks using the WAIT-FOR statement to handle the PROCEDURE-COMPLETE event for the GetOrders request. When GetOrders completes, the associated event procedure, GetOrderRecords, executes. GetOrderRecords returns the TEMP-TABLE parameter and executes the remote user-defined function fnHighVolume (also defined in
order.p
) to provide warning of heavy order traffic. Note that the remote user-defined function is (and can only be) called synchronously.Clearly, the handling of asynchronous requests is more complex than for synchronous requests. While this example is partly procedural, you typically handle all asynchronous requests in an event-driven context using a blocking I/O statement, such as the WAIT-FOR statement. For more information on how to manage asynchronous requests, see the "Managing Asynchronous Requests" section.
Remote Procedure Behavior
In addition to the behavior specified by the RUN statement options, a remote procedure:
NOTE: Remote procedures can also participate in automatic transactions, which are unique to AppServer sessions. For information, see the sections on transaction management in Programming the AppServer."- Executes in the AppServer session as if it was the first procedure executed in the session (top level), using the normal Progress 4GL rules for starting and terminating transactions. For more information about the normal Progress 4GL rules for procedure execution, see the Progress Programming Handbook .
- Can create other objects in the AppServer session, such as other persistent procedures. These objects are only available locally within the Application Server process in which they are created. They cannot be directly shared between a 4GL client application and the AppServer session.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |