Reconnect to Appserver ? ? :)

LINUS

New Member
Hi,

I am running (Graphical User Interface, openedge) application on client-appserver environment. My question is if I am disconnected from the appserver (due to some fluctuation in network) and now when I say
"RUN abc.p ON gshAstraAppserver", It will definitely throw some error messages like: Invalid appserver handle... blabla..

Question :confused: : Whenever there is a fluctuation or the connection to appserver has lost, can we reconnect to the appserver automaticaly?

Question
:confused: : Is there any progress procedure, which gets called when the appserver connections gets lost?

Thank you very much.
Waiting for any positive reponse.


 
Before you run abc.p you should check if gshAstraAppserver:connected() is true.
If not, you should reconnect.
 
The procedure you mention is the disconnect procedure, but it runs on the appserver itself, not on the client.
 
I have more than 1000 of programs where I am using RUN statement without checking the valid-handle() and I do not want to modify all the program. Actually I am looking for a common place(some progress custom files etc), where I want to reconnect to appserver. Thank you.
 
We have a large P4GL GUI client-AppServer application, and solved this issue a few years ago (our app runs across the country (Canada) on a few thousand desktops, eg. its highly vulnerable to network disruptions).

Our convention is to 'wrap' every RUN ON SERVER statement with an include file that detects any errors during the RUN (using RUN ... NO-ERROR, checking the ERROR-STATUS, and also doing it inside an error block) and (if appropriate) it reconnects and retries. You can actually reboot the whole AppServer environment down between RUNs and it will look seamless to the client.

This is 95% effective; the main problem with it is that you have to remember to 'include the include files'. Actually, I detest using include files in this way, but it was the best we could come up with, before or since.

We are now working on a jQuery version of the same app, where we route 100% of the 'RUN ON SERVER' statements through an 'Ajax Manager' kind of object that takes care of all this for us in what seems like a really slick way (I didn't write it, but I use it and compared to what we had to do in P4GL, it feels like pure genius).

I could post some code if it would help.
 
PS: I don't recall exactly but I don't think checking VALID-HANDLE is good enough. IIRC, VALID-HANDLE can be true but trying to use it can still blow up. Our approach is basically "try it and check for errors", as opposed to "try make sure it's going to work first".
 
We have lots of appserver calls, in the RUN ON we use a function in a super procedure to get the handle of the AppServer. In the function a check is done to see if the AppServer is still connected, attempt a retry if not, and if it still fails ask the user if they want to retry:

Code:
      DEF VAR p_happserver AS HANDLE NO-UNDO.
      DEF VAR p_lquit AS LOGICAL NO-UNDO.

      FUNCTION sessionGetAppServer RETURNS HANDLE ():
         DEF VAR lok AS LOGICAL NO-UNDO.

         IF p_happserver = ? THEN
            RETURN SESSION.
         ELSE DO:
            IF NOT VALID-HANDLE( p_happserver ) THEN
               CREATE SERVER p_happserver.
            ELSE IF NOT p_happserver:CONNECTED() THEN DO:
               DO WHILE NOT lOK:
                  IF p_lquit THEN
                     QUIT.
                  lOK = p_happserver:CONNECT( wtsession.appserver_connect, wtsession.user_id, wtsession.password ) NO-ERROR.
                  IF NOT lOK THEN DO:
                     lOK = TRUE.
                     MESSAGE
                        "Connection to AppServer could not be restored.":U SKIP
                        "Attempt to connect again?":U
                     VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO UPDATE lOK.
                     IF lOK THEN
                        lOK = FALSE.
                     ELSE
                        p_lQuit = TRUE.
                  END.
               END.
               /* probably also need to restore some session context? */
            END.
            RETURN p_happserver.
      END FUNCTION.

The AppServer calls then look like:

Code:
RUN blaat ON sessionGetAppServer().

When the initial connection to the AppServer is created, p_happserver is set in the super procedure.
 
Here is our version. I'm curious if its better or not as good as Stefan's, but not enough to figure it out. I noticed ours relies on RUN ... NO-ERROR and his does not; I expect this makes a big difference (in a way its a bad thing on our side, because it's easy for the client programmer to forget, and then nothing works properly). I edited this code to remove anything remotely sensitive to my employer. s_appsrv is a global variable representing the AppServer connection (we're not big on Super Procedures here, but I don't think that is relevant to this situation). So:

Code:
/* <---------- INCLUDE #1 STARTS HERE ----------> */
h_gnas__x_ct = 0.
h_gnas1_x_stop_occured  = YES NO-ERROR.

this_blk:
DO ON ERROR UNDO, RETRY ON STOP UNDO, RETRY:

    IF RETRY AND h_gnas1_x_stop_occured
    THEN RETURN.   
/* <---------- INCLUDE #1 ENDS HERE ----------> */

RUN some_procedure.p ON SERVER s_appsrv NO-ERROR.

/* <---------- INCLUDE #2 STARTS HERE ----------> */
    h_gnas1_x_stop_occured = NO.

    IF ERROR-STATUS:ERROR
    THEN DO:
        IF NOT s_appsrv:CONNECTED()
        THEN DO:
            h_gnas__x_ct = h_gnas__x_ct + 1.
            IF ERROR-STATUS:NUM-MESSAGES =  0  
            THEN DO:
                RUN int_log_error ("ERROR-STATUS = TRUE, NUM-MESSAGES = 0":U).
            END.
            ELSE IF ERROR-STATUS:NUM-MESSAGES <> 0 
            THEN DO h_cterrmsgs = 1 TO ERROR-STATUS:NUM-MESSAGES:
                RUN int_log_error (STRING(ERROR-STATUS:GET-NUMBER(h_cterrmsgs)).
            END.
        END.
        ELSE DO:
            RUN int_show_error("call parameter failure: ").
            RETURN.
        END.

        IF h_gnas__x_ct > 1
        THEN DO:
            RUN int_show_error("unable to reconnect session, connection to server lost.":U).
            RETURN.
        END.

        /* This has logic in it to try different AppServer farms, AIA's, etc., but the main point is that after it runs, s_appsrv will be usable again. */
        RUN DoReconnect (INPUT s_appsrv).


        IF s_appsrv:CONNECTED()
        THEN UNDO this_blk, RETRY.
        ELSE DO:
            IF "{&SEVERITY}":U = "FATAL":U
            THEN DO:
                RUN int_show_error("connection to server lost. terminating client session now.":U).
                QUIT.
            END.
            IF "{&SEVERITY}":U = "SILENT":U
            THEN RETURN.
            RUN int_show_error("connection to server lost":U).
            RETURN.
        END.
    END.
END.

/* <---------- INCLUDE #2 ENDS HERE ----------> */
 
Back
Top