For a given AppServer connection, each asynchronous request is executed in the order that it is submitted, and the event procedures for those requests are executed in the same order that the requests are executed. This order is maintained by the send and response queues associated with the connection, as well as the ABL event queue used to raise PROCEDURE-COMPLETE events.
The send queue queues the requests that are submitted for execution by the client. The response queue queues the responses received on a given AppServer connection for asynchronous requests that have completed execution, but whose event procedure has not yet been executed. Finally, the ABL event queue queues the PROCEDURE-COMPLETE event for each completed request as it is received from the response queue.
The following figure shows how this works, where 1a is the first asynchronous request (AsyncRequest 1a) to AppServer 1 and 2a is the first asynchronous request (AsyncRequest 2a) to AppServer 2, and so forth.
AsyncRequest refers to the execution of an asynchronous RUN statement, and EventProc refers to the execution of an event procedure in response to the PROCEDURE-COMPLETE event handled from the ABL event queue. These requests are further identified by 1 for the AppServer 1 connection and 2 for the AppServer 2 connection, and a letter indicating the order of the request on the client. For simplicity, the example assumes that each AppServer has only one agent to execute requests.
On a given connection (AppServer 1 or AppServer 2), if an asynchronous request is submitted for execution when there is already a request executing on the AppServer, the new asynchronous request is queued on the send queue until all previously submitted asynchronous requests for that connection have executed. Such is the case for AsyncRequests 1d and 2e. The new asynchronous request is only sent to the AppServer for execution once all prior asynchronous requests have completed execution on the AppServer. In the previous figure, AsyncRequests 1b and 2c are currently executing on their respective AppServers.
As each request completes execution, the response to the request is queued on the appropriate response queue and the next request in the send queue is sent to the AppServer. In the previous figure, AsyncRequests 1c and 2d are next in line for execution. Each response remains in the response queue until the corresponding event procedure can be executed in the context of a PROCESS EVENTS or blocking I/O statement. In the previous figure, the PROCEDURE-COMPLETE events for AsyncRequests 1a, 2a, and 2b are all pending execution of their respective event procedures.
The response to an asynchronous request can be received by the client application at any time, but the event procedure associated with that request can be run only if the application is executing a PROCESS EVENTS or blocking I/O statement. Note that the order in which the client handles pending responses for different AppServer connections is undefined. In the previous figure, either the event procedure for AsyncRequest 1a or AsyncRequest 2a can execute first.
Thus, OpenEdge guarantees that the responses from asynchronous requests on the same AppServer connection are handled in order of their execution on the client. However, it does not guarantee the order in which responses are handled from multiple AppServer connections.