Kbase 20609: How to Handle CTRL-BREAK with AppServer Connections
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  15/10/2008 |
|
Status: Verified
SYMPTOM(s):
Multiple AppServer processes are connected to client sessions when the program only uses one.
The application passed the point where it used an AppServer and disconnected but one or more AppServers are still connected.
The user presses CTRL-BREAK and it is not being handled correctly.
AppServer server appears to hang, even though it is not the case.
Pressing CTRL-BREAK, the procedure goes back to the start but the AppServer agent remains connected.
CAUSE:
The block of code that surrounds the AppServer connection statements:
Has no surrounding block other than procedure block or the surrounding block has a "DO ON STOP UNDO, LEAVE:" block.
The "Do On Stop Undo, Leave: will handle the first CTRL-BREAK occurrence, but not subsequent ones, leaving the AppServer agent connected.
FIX:
How to program client procedures to disconnect an AppServer process when a CTRL-BREAK is sent to the procedure:
1. Add a block around the AppServer connection statements when there is no surrounding block other than the procedure block. The new surrounding block must be a transaction block.
2. Modify the block that surrounds the connection statements to use the TRANSACTION keyword or to use a REPEAT block. This makes it a transaction block.
DO TRANSACTION blocks and REPEAT blocks work similarly in how they handle a transaction back-out, and work differently than a non transaction block.
The following client and server procedure, are coded to allow the handling of every occurrence of CTRL-BREAK:
/** Client AppServer procedure **/
DEF VAR hAppSrv AS HANDLE NO-UNDO.
DEF VAR Ret AS LOG NO-UNDO.
DO TRANSACTION ON STOP UNDO, LEAVE:
CREATE SERVER hAppSrv.
ret = hAppSrv:CONNECT("-S dis -H ts6000").
IF NOT ret THEN
DO:
RETURN ERROR "Failed to connect to AppServer".
LEAVE.
END.
RUN AppSrvServer.p ON hAppSrv TRANSACTION DISTINCT.
END.
IF VALID-HANDLE(hAppSrv) THEN
DO:
ret = hAppSrv:DISCONNECT().
DELETE OBJECT hAppSrv.
END.
/** End of client AppServer procedure **/
/** Server AppServer procedure **/
DEF VAR i AS INT NO-UNDO.
DEF VAR x AS INT NO-UNDO.
DEF VAR process-id AS CHAR NO-UNDO.
INPUT THROUGH echo $$ NO-ECHO.
SET process-id.
INPUT CLOSE.
process-id = "./" + process-id.
OUTPUT TO VALUE(process-id).
REPEAT:
i = i + 1.
PUT STRING(i) + " itteration" + chr(13) chr(10).
PAUSE 5.
END.
/** End of server AppServer procedure **/
If a transaction is active at the procedure level or a level prior to the surrounding block, put the surrounding block and AppServer connection code within an internal procedure and call it using a RUN statement. This allows you to implement one of the above mentioned transaction blocks within the internal procedure.