Try OpenEdge Now
skip to main content
Application Migration and Development Guide
Application Development with PAS for OpenEdge : Programming ABL Client Applications : Managing asynchronous requests : Canceling asynchronous requests after a specified time : Examples
 
Examples
The following simple client example uses the CANCEL-REQUESTS-AFTER( ) method:
DEFINE VARIABLE hSrv AS HANDLE  NO-UNDO.
DEFINE VARIABLE bool AS LOGICAL NO-UNDO.

CREATE SERVER hSrv.
hSrv:CONNECT("-URL http://slater:OuterLimits64@zeus:8810/inventory/apsv -sessionModel Session-free").

bool = hSrv:CANCEL-REQUESTS-AFTER(30).
RUN foo.p ON SERVER hSrv ASYNCHRONOUS ("Hello World").

WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.
The following is a more complex example with both client and remote procedures that demonstrate use of both the CANCEL-REQUESTS-AFTER( ) method and the STOP AFTER phrase, which starts a timer on DO blocks on both the client and server. This is the remote procedure, srvrNested3.p:
/* 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.
RETURN "30 Ys".

PROCEDURE spinHere:
  DEFINE INPUT PARAMETER spinLimit AS INT64 NO-UNDO.

  DEFINE VARIABLE loopFlag AS LOGICAL NO-UNDO.
  DEFINE VARIABLE endTime  AS INT64   NO-UNDO.

  ASSIGN
    loopFlag = TRUE
    endTime  = ETIME(FALSE) + spinLimit.

  DO WHILE loopFlag:
    IF (ETIME(FALSE) > endTime) THEN
      loopFlag = FALSE.
  END.
END PROCEDURE.
This is the client procedure that asynchronously invokes the remote procedure (srvrNested3.p):
/* clntNested4.p */
DEFINE BUTTON send-button LABEL "SEND".
DEFINE BUTTON close-button LABEL "CLOSE".

DEFINE VARIABLE ah     AS HANDLE    NO-UNDO.
DEFINE VARIABLE cstr   AS CHARACTER NO-UNDO.
DEFINE VARIABLE rcvcnt AS INTEGER   NO-UNDO.
DEFINE VARIABLE sh     AS HANDLE    NO-UNDO.
DEFINE VARIABLE S1     AS CHARACTER NO-UNDO FORMAT "X(30)".
DEFINE VARIABLE S2     AS CHARACTER NO-UNDO FORMAT "X(30)".
DEFINE VARIABLE xmtcnt AS INTEGER   NO-UNDO.

/* =============================================================== */
FORM send-button close-button
  WITH FRAME buttonFrame.

DEFINE FRAME foo
  S1 AT 1 WITH NO-LABELS.

DEFINE FRAME bar
  S2 AT 1 WITH NO-LABELS.
/* =============================================================== */

ON CHOOSE OF send-button DO:
  RUN runRemoteProc.
  S1 = "Ran proc(" + STRING(xmtcnt) + ")".
  DISPLAY S1 WITH FRAME foo 1 DOWN.
  HIDE FRAME bar.
END.

ON CHOOSE OF close-button DO:
  sh:DISCONNECT().
  DELETE OBJECT sh.
  QUIT.
END.

ON WINDOW-CLOSE OF CURRENT-WINDOW DO:
  sh:DISCONNECT().
  DELETE OBJECT sh.
  QUIT.
END.

ENABLE send-button close-button WITH FRAME buttonFrame.

CREATE SERVER sh.
cstr = "-URL http://slater:OuterLimits64@zeus:8810/inventory/apsv -sessionModel Session-free".
sh:CONNECT(cstr).

WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW OR CHOOSE OF close-button.

sh:DISCONNECT().
DELETE OBJECT sh.
/* =============================================================== */

PROCEDURE runRemoteProc:
  DEFINE VARIABLE ix AS CHARACTER NO-UNDO.
  ASSIGN
    xmtcnt = xmtcnt + 1
    ix     = FILL("X", 30).
  sh:CANCEL-REQUESTS-AFTER(10).
  DO STOP-AFTER 5:
    RUN srvrNested3.p ON SERVER sh ASYNCHRONOUS SET ah
      EVENT-PROCEDURE "remoteProcHandler"
      IN THIS-PROCEDURE (INPUT-OUTPUT ix).
  END.
END PROCEDURE.

/* =============================================================== */

PROCEDURE remoteProcHandler:
  DEFINE INPUT PARAMETER ix AS CHARACTER NO-UNDO.

  ASSIGN
    rcvcnt = rcvcnt + 1
    S2     = "remoteProcHandler(" + STRING(rcvcnt)
    S2     = S2 + IF (SELF:STOP) THEN ") STOPPED"
             ELSE IF (SELF:CANCELLED) THEN ") CANCELLED"
             ELSE ") FINISHED".
  DISPLAY S2 WITH FRAME bar 1 DOWN.
  DELETE OBJECT SELF.
END PROCEDURE.
With this local procedure, the CANCEL-REQUESTS-AFTER( ) method is called on the server handle to establish a time limit of 10 seconds for remote asynchronous procedures; if the timer is already active, the time limit is reset to 10 seconds. The srvrNested3.p is run asynchronously on the server from within a block that specifies a time limit of 5 seconds. The remote procedure does not implicitly adopt the 5 second time limit of the local procedure (as would be the case for running a synchronous remote procedure). In this example, the local time limit of 5 seconds is essentially irrelevant, since it only times the RUN statement. Since this is an asynchronous RUN, it returns immediately after sending the request.
If the response to the request returns before 10 seconds has elapsed, the event procedure remoteProcHandler is run.
If the time limit is exceeded before the response returns, the client session calls CANCEL-REQUESTS( ) method on the server handle. This will cause a STOP message to be sent to the server running the asynchronous request. As with remote synchronous requests, this will cause the STOP condition to be raised in the server application. Depending on the STOP handling logic in the server application, the STOP condition may be returned to the client application in the response. This is indicated by the STOP attribute in the asynchronous request handle, which is set to TRUE prior to running the event procedure.
It is important to note that the time limit for the asynchronous remote procedure call restarts each time the CANCEL-REQUESTS-AFTER( ) method is called. This effectively extends the time limit for any asynchronous requests that have already been run (or queued to run) on that server handle.