The STOP-AFTER phrase on DO, FOR, or REPEAT statement establishes a timer on the block. If the timer expires before execution of the block completes, the AVM raises the STOP condition. At this point, normal STOP condition processing occurs and you can use the ON STOP phrase to handle the STOP.
The rules for executing synchronous remote procedure calls within a timed code block are essentially the same as those for local procedures. Remote procedures may be called within timed blocks or from blocks within timed blocks.
When a timed remote procedure call is executed on an OpenEdge AppServer, the time limit for the procedure is enforced in the client AVM. If the timeout is exceeded, the STOP condition is raised by the client. In this context, a STOP message is sent to the AppServer AVM after the specified time limit had exceeded, which is similar to what happens when an interactive user presses the STOP key.
The following examples illustrate making timed synchronous remote procedure calls on an AppServer:
/* clntNested3.p */
DEFINE VARIABLE clntTimeLimit AS INTEGER NO-UNDO INITIAL 5.
DEFINE VARIABLE hSrv AS HANDLE NO-UNDO.
DEFINE VARIABLE cParm AS CHARACTER NO-UNDO.
CREATE SERVER hSrv.
cParm = FILL("X", 10). /* 10 "X" characters will be sent to server */
hSrv:CONNECT("-URL AppServerDC://hostName/svc").
DO STOP-AFTER clntTimeLimit ON STOP UNDO, LEAVE:
RUN foo.
END.
PROCEDURE foo:
DEFINE VARIABLE cnt AS INTEGER NO-UNDO.
FOR EACH Customer NO-LOCK:
cnt = cnt + 1.
END.
cParm = FILL("X", cnt).
RUN srvrNested3.p ON SERVER hSrv (INPUT-OUTPUT cParm).
END PROCEDURE.
In this example, the client program (clntNested3.p) connects to the AppServer, and runs the local procedure foo within a timed code block, specifying STOP-AFTER 5. The procedure foo counts the number of customer records, and then fills the character variable cParm with "X" characters. The remote procedure srvrNested3.p is then called. Because this remote procedure call is made from within the timed procedure foo, srvrNested3.p is implicitly run as a timed procedure; the time limit for this call is the time remaining for the timed block calling foo (5 seconds, less the time required to count the number of customer records). The client AVM begins timing this when the remote procedure call is made. If the call to srvrNested3.p does not return in the client AVM within the 5 second time limit, the client AVM will issue a STOP message to the AppServer. When the AppServer receives the STOP message, the STOP condition will be raised in the AppServer AVM, as shown:
/* srvrNested3.p */
DEFINE INPUT-OUTPUT PARAMETER p1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE srvrTimeLimit AS INTEGER NO-UNDO INITIAL 10.
DEFINE VARIABLE spinLimit AS INT64 NO-UNDO INITIAL 15000.
p1 = FILL("Y", 30). /* 30 "Y" characters will be sent to the client */
DO STOP-AFTER srvrTimeLimit:
RUN spinHere (spinLimit).
END.
DO WHILE loopFlag:
IF (ETIME(FALSE) > endTime) THEN
loopFlag = FALSE.
END.
END PROCEDURE.
In srvrNested3.p on the AppServer agent, the INPUT-OUTPUT parameter p1 is filled with 30 "Y" characters, and the spinHere procedure is called from within a timed code block, with the time limit of 10 seconds (the value of srvrTimeLimit). In this example, spinHere is supposed to return after 15 seconds (the value of spinLimit). The procedure will ostensibly time out after 10 seconds, and the STOP condition will be raised. However, the client AVM will issue the STOP message to the server after 5 seconds, the STOP condition will be raised in the client after 5 seconds (approximately).
Because srvrNested3.p employs default STOP handling (that is, the srvrNested3.p program does not specify an ON STOP phrase), the STOP condition is not handled by the server AVM. The timeout is consequently propagated back to the client AVM.
It is important to note that the remote procedure call could also be made within an explicit timed block. As with the local case, the actual time limit value used by the RUN would be the smaller of the implicit and the explicit time limit values.
Note: Another way to time limit procedure calls is to set the ubroker property called srvrExecutionTimeLimit will in the [UBroker] section of the ubroker.properties file. This is a non-negative integer property that specifies the maximum time in seconds that a remote procedure may execute on the given AppServer. This timeout value applies to all remote procedures that execute on the AppServer.