SAX Reader blocks destructor????

Posted by Thomas Mercer-Hursh on 28-May-2014 11:56

I have a series of programs which are a part of this tool I am writing which run in sequence.  Each writes start and stop messages to the log-manager log as well as any unexpected errors.  Each has its own log for "expected" exceptions written to with a logging object.  Almost programs are classes with a very similar structure - an Initialize() method which writes the start message, checks the setup, and writes a starting message in the exception list and a Process() method which does the work.  Most classes are a subclass of a class which builds a list of files to process according to the setup criteria and a super() call for this is the first thing in Process.  Most then call ScanAll() which loops through the list of files and calls ScanOne() which does the actual work.  Three of the programs use a SAX-reader to process the input file.  The actual procedure is started in Initialize(), ScanOne() checks that it is a correct file to process and does some setup, and then calls ProcessXref().  That method sets up the SAX reader and calls it.  The actual methods to handle StartElement, EndElement, and whatever are in the main class so the event procedure is just a skeleton that does callbacks to the main object.

This is all working, but with one anomaly.  I know that the files are processed and I know that the loop in ScanAll() finishes without any errors.  There are both a number of strategic catch blocks within the code and a master catch in the calling procedure which should capture anything into the log.

But, the Destructor of all classes, in addition to any cleanup, if any, writes a final line to the exception log about how much work it has done and a Stop line to the log-manager.  This works everywhere except in the classes with the SAX parsers.  There, I am getting none of the messages from the Destructor and no error messages.

Here is one of the Destructors: 

	destructor public BuildTableLinks ( ):
    obReport:WriteMessage ( substitute("End of scan with &1 total files; &2 compiled with &3 table links and &4 column links",inTotalFiles, inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).
	  if valid-handle(hnXrefHandler)
	  then do:
      delete procedure hnXrefHandler.
      hnXrefHandler = ?.
	  end.
	  else log-manager:write-message ("BuildTableLinks: Destructor: Invalid handle for hnXrefHandler").
    log-manager:write-message ( substitute( "End of BuildTableLinks with &1 exceptions", inTotalExceptions )).
	end destructor.



Any ideas about what is happening here? 

All Replies

Posted by Mike Fechner on 28-May-2014 12:02

If the destructor is not called, we need to see the rest of the code.

Are you following your own suggestions and deleting the object explicitly or relying on the GC?

How did you handle the SAX reading? A PP with a ref to the call? Is that still around, holding a reference?

Von meinem Windows Phone gesendet

Von: Thomas Mercer-Hursh
Gesendet: ‎28.‎05.‎2014 18:56
An: TU.OE.Development@community.progress.com
Betreff: SAX Reader blocks destructor????

Thread created by Thomas Mercer-Hursh

I have a series of programs which are a part of this tool I am writing which run in sequence.  Each writes start and stop messages to the log-manager log as well as any unexpected errors.  Each has its own log for "expected" exceptions written to with a logging object.  Almost programs are classes with a very similar structure - an Initialize() method which writes the start message, checks the setup, and writes a starting message in the exception list and a Process() method which does the work.  Most classes are a subclass of a class which builds a list of files to process according to the setup criteria and a super() call for this is the first thing in Process.  Most then call ScanAll() which loops through the list of files and calls ScanOne() which does the actual work.  Three of the programs use a SAX-reader to process the input file.  The actual procedure is started in Initialize(), ScanOne() checks that it is a correct file to process and does some setup, and then calls ProcessXref().  That method sets up the SAX reader and calls it.  The actual methods to handle StartElement, EndElement, and whatever are in the main class so the event procedure is just a skeleton that does callbacks to the main object.

This is all working, but with one anomaly.  I know that the files are processed and I know that the loop in ScanAll() finishes without any errors.  There are both a number of strategic catch blocks within the code and a master catch in the calling procedure which should capture anything into the log.

But, the Destructor of all classes, in addition to any cleanup, if any, writes a final line to the exception log about how much work it has done and a Stop line to the log-manager.  This works everywhere except in the classes with the SAX parsers.  There, I am getting none of the messages from the Destructor and no error messages.

Here is one of the Destructors: 

	destructor public BuildTableLinks ( ):
    obReport:WriteMessage ( substitute("End of scan with &1 total files; &2 compiled with &3 table links and &4 column links",inTotalFiles, inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).
	  if valid-handle(hnXrefHandler)
	  then do:
      delete procedure hnXrefHandler.
      hnXrefHandler = ?.
	  end.
	  else log-manager:write-message ("BuildTableLinks: Destructor: Invalid handle for hnXrefHandler").
    log-manager:write-message ( substitute( "End of BuildTableLinks with &1 exceptions", inTotalExceptions )).
	end destructor.



Any ideas about what is happening here? 

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Posted by Marian Edu on 28-May-2014 12:21

On 05/28/2014 07:56 PM, Thomas Mercer-Hursh wrote:
> destructor public BuildTableLinks ( ):
> obReport:WriteMessage ( substitute("End of scan with &1 total files; &2 compiled with &3 table links and &4 column links",inTotalFiles, inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).

any chance the obReport object is invalidat that point? if it is there
is no error handling on that line so it won't get any furtherin the
destructor

--
m.edu
keep it simple
http://www.ganimede.ro
http://ro.linkedin.com/in/marianedu
medu@ganimede.ro
mobile: +40 740 036 212
skype: marian.edu

Posted by jmls on 28-May-2014 12:24

my first guess is that the sax objects aren't been GC'd because they
are referenced somewhere. Therefore the destructor won't get run

Julian

On 28 May 2014 18:21, Marian Edu wrote:
> Re: SAX Reader blocks destructor????
> Reply by Marian Edu
> On 05/28/2014 07:56 PM, Thomas Mercer-Hursh wrote:
>> destructor public BuildTableLinks ( ):
>> obReport:WriteMessage ( substitute("End of scan with &1 total files; &2
>> compiled with &3 table links and &4 column links",inTotalFiles,
>> inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).
>
> any chance the obReport object is invalidat that point? if it is there
> is no error handling on that line so it won't get any furtherin the
> destructor
>
> --
> m.edu
> keep it simple
> http://www.ganimede.ro
> http://ro.linkedin.com/in/marianedu
> medu@ganimede.ro
> mobile: +40 740 036 212
> skype: marian.edu
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.



--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com

"The bitterness of poor quality remains long after the sweetness of
low price is forgotten”

Follow dot.r on http://twitter.com/DotRlimited

Posted by Thomas Mercer-Hursh on 28-May-2014 12:39

I think Mike is pointing the right direction.  As it happens, I am not explicitly deleting in the driver program, which I should do.  It is, however, a local variable in the method in the driver class (see below)  I will also move the cleanup of the SAX reader outside the destructor so that it is called explicitly and in advance.

  method public void ProcessTableLinks ():
    define variable mobBuildTableLinks as class BuildTableLinks no-undo.
    
    mobBuildTableLinks = new BuildTableLinks ( chSourceDirectory ).
    
    mobBuildTableLinks:chIncludeExtensions = chCompilableExtensions.
    mobBuildTableLinks:lgExcludeNoExtension = lgExcludeNoExtension.
    mobBuildTableLinks:chRunDestination = chRunDestination.
    mobBuildTableLinks:chXrefDestination = chXrefDestination.
    mobBuildTableLinks:chReportDestination = chReportDestination + chSeparator + "BuildTableLinksExceptions.txt".
    
    mobBuildTableLinks:Initialize().
    mobBuildTableLinks:Process().
        
  end method.


I am going to add a cleanup and explicit delete.  Thanks.

Posted by Thomas Mercer-Hursh on 28-May-2014 14:22

Those changes solved the problem so it must have been the reference from the event handler keeping the destructor from firing.

Posted by Peter Judge on 28-May-2014 14:26

For future reference, you can use the DynObjects.Class log entry type for the log-manager to see which objects are being GC'ed (also destroyed manually) and when. Handy for these cases where you want to first make sure that the destructor is actually firing.
 
-- peter
 
[collapse]
From: Thomas Mercer-Hursh [mailto:bounce-tamhas@community.progress.com]
Sent: Wednesday, 28 May, 2014 15:22
To: TU.OE.Development@community.progress.com
Subject: RE: SAX Reader blocks destructor????
 
Reply by Thomas Mercer-Hursh

Those changes solved the problem so it must have been the reference from the event handler keeping the destructor from firing.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Thomas Mercer-Hursh on 28-May-2014 14:35

Yeah, that is one of the currently commented out options in the launcher program which I use when debugging.  It simply hadn't occurred to me that the object wasn't being deleted and that was why the destructor wasn't firing.  It should have for any number of reasons, not the least of which was that the unique feature of the classes that were failing was the event-handler procedure.  Clues, clues, clues, but no lightbulb.  Worst of all, I think I may have had the clean up code for the event handler in a separate method at one point and then moved it into the destructor because I didn't want to call a cleanup method universally since there was nothing to clean up in all the rest.

Posted by Marian Edu on 04-Jun-2014 12:13

what's the thing with that GC, is that a feature of a bug? :)

I still like to do the clean-up myself (even if it means being
suicidal)... at least don't have any issues with the GC although I'm
sure it's the best thing since sliced bread ;)

I still hold my bet on the lack of error handling in that destructor.

[collapse]On 05/28/2014 08:24 PM, jmls wrote:
>[collapse] From: jmls
> Post: Re: SAX Reader blocks destructor????
> Posted in: OpenEdge Development
> Link: http://community.progress.com/technicalusers/f/19/p/10494/39299.aspx#39299
>
> my first guess is that the sax objects aren't been GC'd because they
> are referenced somewhere. Therefore the destructor won't get run
>
> Julian
>
> On 28 May 2014 18:21, Marian Eduwrote:
>> Re: SAX Reader blocks destructor????
>> Reply by Marian Edu
>> On 05/28/2014 07:56 PM, Thomas Mercer-Hursh wrote:
>>> destructor public BuildTableLinks ( ):
>>> obReport:WriteMessage ( substitute("End of scan with &1 total files; &2
>>> compiled with &3 table links and &4 column links",inTotalFiles,
>>> inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).
>> any chance the obReport object is invalidat that point? if it is there
>> is no error handling on that line so it won't get any furtherin the
>> destructor
>>
>> --
>> m.edu
>> keep it simple
>> http://www.ganimede.ro
>> http://ro.linkedin.com/in/marianedu
>> medu@ganimede.ro
>> mobile: +40 740 036 212
>> skype: marian.edu
>> Stop receiving emails on this subject.
>>
>> Flag this post as spam/abuse.
>
>


--
m.edu
keep it simple
http://www.ganimede.ro
http://ro.linkedin.com/in/marianedu
medu@ganimede.ro
mobile: +40 740 036 212
skype: marian.edu[/collapse][/collapse]

Posted by Marian Edu on 04-Jun-2014 12:44

now that's odd... did sent the reply same day (5.28), either got stuck
on my provider network or stumbled upon a worm hole :)

[collapse]On 06/04/2014 08:14 PM, Marian Edu wrote:
>[collapse] From: Marian Edu
> Post: Re: SAX Reader blocks destructor????
> Posted in: OpenEdge Development
> Link: http://community.progress.com/technicalusers/f/19/p/10494/39657.aspx#39657
>
> what's the thing with that GC, is that a feature of a bug? :)
>
> I still like to do the clean-up myself (even if it means being
> suicidal)... at least don't have any issues with the GC although I'm
> sure it's the best thing since sliced bread ;)
>
> I still hold my bet on the lack of error handling in that destructor.
>
> [collapse]On 05/28/2014 08:24 PM, jmls wrote:
>>[collapse] From: jmls
>> Post: Re: SAX Reader blocks destructor????
>> Posted in: OpenEdge Development
>> Link: http://community.progress.com/technicalusers/f/19/p/10494/39299.aspx#39299
>>
>> my first guess is that the sax objects aren't been GC'd because they
>> are referenced somewhere. Therefore the destructor won't get run
>>
>> Julian
>>
>> On 28 May 2014 18:21, Marian Eduwrote:
>>> Re: SAX Reader blocks destructor????
>>> Reply by Marian Edu
>>> On 05/28/2014 07:56 PM, Thomas Mercer-Hursh wrote:
>>>> destructor public BuildTableLinks ( ):
>>>> obReport:WriteMessage ( substitute("End of scan with &1 total files; &2
>>>> compiled with &3 table links and &4 column links",inTotalFiles,
>>>> inTotalCompiled, inTotalTableLinks, inTotalColumnLinks ) ).
>>> any chance the obReport object is invalidat that point? if it is there
>>> is no error handling on that line so it won't get any furtherin the
>>> destructor
>>>
>>> --
>>> m.edu
>>> keep it simple
>>> http://www.ganimede.ro
>>> http://ro.linkedin.com/in/marianedu
>>> medu@ganimede.ro
>>> mobile: +40 740 036 212
>>> skype: marian.edu
>>> Stop receiving emails on this subject.
>>>
>>> Flag this post as spam/abuse.
>>
>


--
m.edu
keep it simple
http://www.ganimede.ro
http://ro.linkedin.com/in/marianedu
medu@ganimede.ro
mobile: +40 740 036 212
skype: marian.edu[/collapse][/collapse][/collapse][/collapse]

Posted by Thomas Mercer-Hursh on 04-Jun-2014 13:29

I do think there have been a few mail wormholes around lately.  I have gotten random pieces of inbound mail twice, days apart.

And, yes, I do like cleaning up my own trash.

This thread is closed