Building Distributed
Applications
Using the Progress AppServer
Handling the Response from an Asynchronous Request
When an asynchronous request completes execution, it sends a response to the AppServer client, which places it on the response queue for the appropriate server handle. To signify that the response is ready to be processed, the PROCEDURE-COMPLETE event is placed on the event queue where it can be processed in the context of blocking I/O statements, such as WAIT-FOR or the PROCESS EVENTS statement.
PROCEDURE-COMPLETE Events
The PROCEDURE-COMPLETE event is an event on the asynchronous request handle. It indicates that the asynchronous request associated with the handle has completed execution, and that the corresponding event procedure can be executed. Progress executes the event procedure in the context of a blocking I/O statement much like it executes the trigger for a user-interface event.
Note that you do not have to specify the PROCEDURE-COMPLETE event explicitly in your client code. Progress processes the event like any other 4GL event. However, you do not have to define a trigger for the event (for example, using an ON statement) because you specify an event procedure in the RUN...ASYNCHRONOUS statement that defines the “trigger code” for the event.
To process a PROCEDURE-COMPLETE event for a particular asynchronous request handle, Progress:
- Decrements the ASYNC-REQUEST-COUNT attribute on the following handles:
- Sets the COMPLETE attribute for the asynchronous request handle to TRUE.
- Sets the STOP, QUIT, or ERROR attribute for the asynchronous request handle appropriately as indicated by the response message from the AppServer, and stores any error information returned from the AppServer for the request in the ERROR-STATUS system handle.
- Sets the return value for the RETURN-VALUE function, if a return value was returned by the AppServer.
- Attempts to execute the event procedure specified by the EVENT-PROCEDURE and the EVENT-PROCEDURE-CONTEXT attributes for the asynchronous request handle, if EVENT-PROCEDURE is not the empty string (“”), and:
- Sets each INPUT parameter for the event procedure to the unknown value (?) or, if the parameter is a TEMP-TABLE, the TEMP-TABLE remains unchanged, if the response message indicates that the remote request finished with a STOP, ERROR, or QUIT condition.
- Sets the INPUT parameter values for the event procedure to the OUTPUT and INPUT-OUTPUT parameter values returned by the remote procedure, if the response message indicates that the remote request completed successfully.
- Displays an error message, if a specified event procedure fails to execute for any reason.
Event Procedures
To handle the response from an asynchronous request, you must define an event procedure. In this context, an event procedure is an internal procedure that executes in response to a PROCEDURE-COMPLETE event. To define an event procedure you must:
Typical places where you might define the specified internal procedure include:
- The same procedure context as the RUN...ASYNCHRONOUS statement that specifies the event procedure.
- An external procedure context that you specify using the EVENT-PROCEDURE option on the RUN...ASYNCHRONOUS statement using its procedure handle. In this case, the external procedure context must be active in the client session before you execute the RUN...ASYNCHRONOUS statement.
You must define the specified internal procedure with INPUT parameters that correspond in type and order to the OUTPUT and INPUT-OUTPUT parameters that you specify on the RUN...ASYNCHRONOUS statement.
To receive results from the asynchronous request in an event procedure, you can access:
- The asynchronous request handle for the request using the SELF system handle
- The attributes and methods of the ERROR-STATUS system handle to obtain error information from the request
- Values passed as output parameters from the remote procedure to corresponding input parameters in the event procedure
- The RETURN-VALUE function to get the return value from the request
Obtaining Error Information
With an asynchronous remote procedure request, the RUN...ASYNCHRONOUS statement returns once the client request has been validated. Any errors that occur while processing the RUN...ASYNCHRONOUS statement are returned as a STOP or ERROR condition in the context of the RUN...ASYNCHRONOUS statement. Information on errors that occur once the asynchronous request has been submitted can be obtained by using the ERROR-STATUS system handle within the event procedure for the asynchronous request.
If the asynchronous request completes with a condition, you can use attributes on the asynchronous request handle to determine the condition that the request completed with, as follows:
Note that any asynchronous request that raises the STOP condition (by executing the STOP statement), and does not handle the condition itself, also sets the STOP attribute of its corresponding asynchronous request handle to TRUE.
If any errors occur when the event procedure attempts to execute, Progress displays an error message in the context of the blocking I/O statement, and no information is stored in the asynchronous request handle. Errors where this might occur include, for example, an event procedure whose INPUT parameters do not match in order and type with the output parameters from the remote request.
Obtaining Parameter Values
As explained earlier, the values returned for OUTPUT or INPUT-OUTPUT parameters on an asynchronous remote procedure are not returned to the RUN statement as for a synchronous remote procedure. Instead, they are returned in the corresponding INPUT parameters of the specified event procedure.
Note that INPUT parameters in an event procedure observe the same rules of definition and scoping as any internal procedure:
Thus, in this example, the order-table TEMP-TABLE (defined in the outer block) receives its content directly from the order-table INPUT parameter of the GetOrderRecords event procedure. However, you must explicitly assign the icount variable (defined in the outer block) to the order-count parameter in order to make the parameter value available to the outer block. (That is, if you define the INPUT parameter as icount instead of order-count, Progress does not automatically make the parameter value available as icount in the outer block. Only the TABLE parameter is scoped to the outer block and thus receives its value from the parameter.)
Note also that the event procedure checks for and handles any unhandled conditions generated from the execution of
order.p
using AppServer error-handling mechanisms.Obtaining the Return Value
You can obtain the return value for a remote procedure that you call asynchronously by invoking the RETURN-VALUE function within the event procedure that handles the asynchronous request. This function thus returns the value specified by a corresponding RETURN statement executed in the remote procedure. As for a synchronous request, if the remote procedure returns no value in the RETURN statement, the RETURN-VALUE function returns the empty string ("").
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |