Problems using QUIT in PASOE to simulate "classic"

Posted by dbeavon on 27-Nov-2018 20:22

The docs say that we can use the QUIT statement from within an ABL session in pasoe.

https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/pasoe-migrate-develop/migrating-classic-state-reset-operating-mode.html

This is supposed to simulate the "classic" state-reset behavior.  It is done in conjunction with the manipulation of "SESSION:SERVER-CONNECTION-BOUND", which set to true when a connection is made, and false during disconnection.

I'd like to use QUIT in order to clear out any memory leakage that may be going on within the ABL session.  However we are finding that the performance is awful when running ABL programs on a network file share.  It subverts the purpose of the "-q" client session parameter and causes programs to get reloaded continuously (r-code is too large and there are 1,000's of individual programs).

It is probably wishful thinking, but does anyone know a mechanism to do the equivalent of a QUIT, but *without* unloading all the cached programs from memory?  I'd like it to clear out all persistent procedures, delete static objects, perform GC, and so on.  (Or perhaps there is a way to enumerate and delete persistent procedures manually?)

Thanks in advance.

Posted by Peter Judge on 27-Nov-2018 20:28

>  (Or perhaps there is a way to enumerate and delete persistent procedures manually?)

This can be done relatively simply. Take a look at the SESSION system handle, in particular the FIRST-*  attributes, like FIRST-PROCEDURE and FIRST-OBJECT . Once you have the relevant thing (a handle for the PROCEDURE) you can walk a tree with the NEXT-SIBLING attribute.

You can see an example at github.com/.../Session.cls .
 
        hTemp = session:first-procedure.
        do while valid-handle(hTemp):        
            if hTemp:file-name eq pcName then
                oProcedures:Add(new WidgetHandle(hTemp)).
 
            hTemp = hTemp:next-sibling.
        end.
 
You can add  that to a session’s deactivate procedure and see/destroy whatever you want to.
 
 

Posted by Mike Fechner on 27-Nov-2018 20:26

Network share???? And complaining about performance?
 
Anyway, iterate from SESSION:FIRST-PROCEDURE through the NEXT-SIBLING’s
 
ASSIGN hProc = SESSION:FIRST-PROCEDURE .
 
DO WHILE VALID-HANDLE (hProc):
   ASSIGN hNext  = hProc:NEXT-SIBLING.
   DELETE PROCEDREU hProc.
   ASSIGN hPRoc = hNext.
END.
 

All Replies

Posted by Mike Fechner on 27-Nov-2018 20:26

Network share???? And complaining about performance?
 
Anyway, iterate from SESSION:FIRST-PROCEDURE through the NEXT-SIBLING’s
 
ASSIGN hProc = SESSION:FIRST-PROCEDURE .
 
DO WHILE VALID-HANDLE (hProc):
   ASSIGN hNext  = hProc:NEXT-SIBLING.
   DELETE PROCEDREU hProc.
   ASSIGN hPRoc = hNext.
END.
 

Posted by Peter Judge on 27-Nov-2018 20:28

>  (Or perhaps there is a way to enumerate and delete persistent procedures manually?)

This can be done relatively simply. Take a look at the SESSION system handle, in particular the FIRST-*  attributes, like FIRST-PROCEDURE and FIRST-OBJECT . Once you have the relevant thing (a handle for the PROCEDURE) you can walk a tree with the NEXT-SIBLING attribute.

You can see an example at github.com/.../Session.cls .
 
        hTemp = session:first-procedure.
        do while valid-handle(hTemp):        
            if hTemp:file-name eq pcName then
                oProcedures:Add(new WidgetHandle(hTemp)).
 
            hTemp = hTemp:next-sibling.
        end.
 
You can add  that to a session’s deactivate procedure and see/destroy whatever you want to.
 
 

Posted by dbeavon on 27-Nov-2018 22:12

OK thanks for the responses.  Hopefully it is the case that most of my leaks will be located in the (legacy) persistent procedures which aren't being managed by any garbage collector. That way I can just clean them up during my ("state-reset") disconnection procedure, as you indicated.

If my leaks are happening anywhere else, then I suppose they will wait to be cleaned up when I trim inactive ABL sessions from the PASOE agent every hour.

Posted by gus bjorklund on 27-Nov-2018 23:24

> On Nov 27, 2018, at 3:23 PM, dbeavon wrote:

>

> It is probably wishful thinking, but does anyone know a mechanism to do the equivalent of a QUIT, but *without* unloading all the cached programs from memory?

With pasoe, you should consider using stateful applications and keep the session alive for the life of the client. Properly configured, this will provide good performance as the agents worker threads can switch amongst the sessions hat have ben set up. When a request arrives, a worker thread will handle it, associating with the relevant 4GL session in the agent.

Posted by Stefan Drissen on 28-Nov-2018 12:20

Whenever a connection to a foreign DataServer database was lost the session was so unusable that all our attempts to reconnect and restart it nicely failed that we ultimately resorted to blowing up the stack:

FUNCTION terminateAgent RETURNS LOGICAL PRIVATE (

  i_cprocedure   AS CHARACTER,

  i_cerror       AS CHARACTER

):

  IF i_cprocedure > "" THEN

     MESSAGE

        SUBSTITUTE(

           "&1: &2, terminating agent.":u,

           i_cprocedure,

           IF i_cerror > "" THEN

              i_cerror

           ELSE

              "A fatal error occurred":u

        ).

  terminateAgent( ?, ? ).

END FUNCTION. /* terminateAgent */

This thread is closed