OOABL and cleaning up handles

Posted by asthomas on 02-Jul-2014 08:23

A question for the OOABL experts out there...

OE 11.3.2

I have some OOABL code that has been updated so that method output parameters returning handles for temp-table, datasets etc. have been changed to use return values on the methods instead.

e.g. 

METHOD PUBLIC VOID rtbGetWorkspace(
    INPUT pcWorkspaceId AS CHARACTER,
    OUTPUT TABLE-HANDLE phTT ):

RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (
INPUT pcWorkspaceId,
OUTPUT TABLE-HANDLE phTT).

RETURN.

FINALLY:
    DELETE OBJECT phTT NO-ERROR.
END FINALLY.

END METHOD.

Has been changed to: 

METHOD PUBLIC HANDLE rtbGetWorkspace(
INPUT pcWorkspaceId AS CHARACTER):

DEFINE VARIABLE hTT AS HANDLE NO-UNDO.

RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (
INPUT pcWorkspaceId,
OUTPUT TABLE-HANDLE hTT).

RETURN hTT.

END METHOD.

Initially, I had the DELETE OBJECT code in the FINALLY of the updated method. But this resulted in the code not working any more, as the returned hTT handle was then ?. 

Is it correct that it is not longer necessary to delete handles explicitly to avoid memory leaks in use cases like this? 

TIA

All Replies

Posted by Peter Judge on 02-Jul-2014 08:29

Returning a HANDLE is not the same as returning a DATASET-HANDLE (regardless of whether you do it via return values or parameters). The HANDLE is a shallow reference/pointer; the dataset-handle is a deep copy (typically). If you get a handle and the object that holds the TT/PDS that the handle refers  is GC'ed, then the handle will point at nothing, hence errors.

> Is it correct that it is not longer necessary to delete handles explicitly to avoid memory leaks in use cases like this? 

You should always manually clean up handle-based objects, regardless of OO/procedural code.
 
-- peter
 
[collapse]
From: asthomas [mailto:bounce-asthomas@community.progress.com]
Sent: Wednesday, 02 July, 2014 09:24
To: TU.OE.General@community.progress.com
Subject: [Technical Users - OE General] OOABL and cleaning up handles
 
Thread created by asthomas

A question for the OOABL experts out there...

OE 11.3.2

I have some OOABL code that has been updated so that method output parameters returning handles for temp-table, datasets etc. have been changed to use return values on the methods instead.

e.g. 

METHOD PUBLIC VOID rtbGetWorkspace(
    INPUT pcWorkspaceId AS CHARACTER,
    OUTPUT TABLE-HANDLE phTT ):

RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (
INPUT pcWorkspaceId,
OUTPUT TABLE-HANDLE phTT).

RETURN.

FINALLY:
    DELETE OBJECT phTT NO-ERROR.
END FINALLY.

END METHOD.

Has been changed to: 

METHOD PUBLIC HANDLE rtbGetWorkspace(
INPUT pcWorkspaceId AS CHARACTER):

DEFINE VARIABLE hTT AS HANDLE NO-UNDO.

RUN rtb/proxy/p/rtbGetWorkspace.p ON AppServerHandle (
INPUT pcWorkspaceId,
OUTPUT TABLE-HANDLE hTT).

RETURN hTT.

END METHOD.

Initially, I had the DELETE OBJECT code in the FINALLY of the updated method. But this resulted in the code not working any more, as the returned hTT handle was then ?. 

Is it correct that it is not longer necessary to delete handles explicitly to avoid memory leaks in use cases like this? 

TIA

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Thomas Mercer-Hursh on 02-Jul-2014 09:44

I would suggest that the fundamental issue here is violating encapsulation by returning a handle in the first place.  Quite aside from the nicities of OO, that is bound to make it ambiguous where you should clean up those references.  Instead, bundle all of the functionality for manipulating the TT or DS within the object and return ordinary values in response to methods.  Much cleaner.

Posted by Marian Edu on 02-Jul-2014 14:31

there is nothing wrong with returning complex data in a
temp-table/dataset structure... we can't always return just 'ordinary
values' :)

returning a handle to such a 'private' structure used for keeping state
information can be seen as encapsulation violation but don't turn this
into a generalization ;)

On 07/02/2014 05:45 PM, Thomas Mercer-Hursh wrote:
>[collapse] From: Thomas Mercer-Hursh
> Post: RE: OOABL and cleaning up handles
> Posted in: OpenEdge General
> Link: http://community.progress.com/technicalusers/f/26/p/11168/41445.aspx#41445
>
> I would suggest that the fundamental issue here is violating encapsulation by returning a handle in the first place. Quite aside from the nicities of OO, that is bound to make it ambiguous where you should clean up those references. Instead, bundle all of the functionality for manipulating the TT or DS within the object and return ordinary values in response to methods. Much cleaner.
>
>
> --
> You were sent this email because you opted to receive email notifications when someone created a new thread.
>
> To unsubscribe[collapse] from:
> - ...only this thread, disable notifications at http://community.progress.com/technicalusers/f/26/p/11168/41445.aspx#41445.
> - ...all email notifications from Progress Community, navigate to "Settings", click on the "Email" tab, then under the "Email Configuration" section, set Send Notifications to "No".
>
>


--
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 Thomas Mercer-Hursh on 02-Jul-2014 14:41

I am waiting for an actual use case.  I can imagine circumstances where one would want to return an object which encapsulated a TT, but no use cases yet where there is a need for two objects to share a TT definition.

Posted by Mike Fechner on 02-Jul-2014 14:47

Maybe you should start a seperate thread for that discussion?

The OP’s question has already been answered. So why start the same old endless never agreed religious debate over again?

Posted by asthomas on 02-Jul-2014 14:55

Thanks Peter - the procedures and classes using this wrapper class are cleaning up. So there should not be a problem there.

FYI - The code is constructed as it is right now because it was created as a an OOABL wrapper for a bunch of procedure based proxies that return temp-tables with data. So it may not be best practice - but it works ;-)

Posted by Thomas Mercer-Hursh on 02-Jul-2014 15:02

Mike, the reason for bringing it up is because sometimes the right answer to a question is that one shouldn't be trying to do the thing one is asking about.  Circumstances like Thomas' may cause one to violate good principles, but one shouldn't do it casually or, more importantly, without knowing what one is doing.

Posted by Mike Fechner on 02-Jul-2014 15:08

But aren’t there enough discussion of that kind on this forum for those looking for that advice?

“but no use cases yet where there is a need for two objects to share a TT definition.”

Did you actually look at the source from the original post? The class with the method returning the temp-table’s handle does not keep knowledge about the temp-table. So from my point of view, there is no shared temp-table anywhere and anytime. It’s more like a factory returning an object to the caller.

 

Posted by Thomas Mercer-Hursh on 02-Jul-2014 15:23

Then why not wrap it and remove the ambiguity.  A factory is exactly the kind of case I was referring to.  Now, to be sure, in Thomas' case he is trying to interface with legacy code so at some point one has to decide what interface is acceptable and, in the short run, that can mean defining interfaces which one wouldn't otherwise use.  Thomas' original question is indicative of the ambiguity of the situation.

Posted by Mike Fechner on 02-Jul-2014 15:26

Thomas' original question is indicative of the ambiguity of the situation.
 
Not to me.

Posted by Thomas Mercer-Hursh on 02-Jul-2014 15:38

Not knowing whether he should be deleting the object in this object, where he had been or deleting it somewhere else isn't indication of ambiguity?   Non-ambiguous would be having it be immediately clear where the delete should happen.

Posted by Mike Fechner on 02-Jul-2014 15:44

And hiding the temp-table type object in a Progress.Lang.Object inheriting object does change this exactly why? Because you feel smarter because you put a class around it?

Just because one object is handle based and the other is PLO derived does not change anything on the question who should be deleting that thing. His question then would be, where should my object be deleted. Is that of a different quality? Certainly not. A temp-table is an object. You can return references, you can return a copy, you can keep the reference when returning or not.

 

Posted by Jeff Ledbetter on 02-Jul-2014 15:56

Since I wrote the called code, I will comment. :)

The code is not "legacy code"; it is the server API layer for our plug-in client.

The procedure is this particular layer is returning a TABLE-HANDLE (not an HANDLE) and cannot return an encapsulated ABL object because it is coming across the appserver whose principal receiver is a java client. The TABLE-HANDLE parameter translates into a resultSet when invoked via java via the proxy-generated classes.

So as one can see, it's not always black and white. Sometimes you gotta build for the gray areas as well.

Anyhow, yes Thomas you should always do a DELETE OBJECT for TABLE-HANDLE parameters.

Posted by Thomas Mercer-Hursh on 02-Jul-2014 15:59

Unlike a PLO object, aka a real object since a TT or DS has a ways to go before one can really treat it like an object, the real object does not need to have its definition every place it is used.  Unlike a TT, one can bury all the access logic in the real object so that the outside world sees only the methods and properties of the object.  And, unlike a TT defined in multiple compile units, it is usually quite clear who should delete a real object .... either based on the you made it, you delete it rule or because the object is passed to a consumer and the consumer defines the end of life.

Posted by Thomas Mercer-Hursh on 02-Jul-2014 16:01

Jeff, sounds like a perfect case for turning the TT into a JSON object which can be easily consumed by any manner of destination clients.  JSON objects serialize to simple strings which have none of the issues of TTs.

Posted by Mike Fechner on 02-Jul-2014 16:03

Beg my pardon, but I cannot see how this generalized statement applies to the original question. Hence my suggestion to start a different discussion thread to make it easier for future olks to find the probably valuable information you are providing in the right place.

Posted by Mike Fechner on 02-Jul-2014 16:04

Jeff, sounds like a perfect case for turning the TT into a JSON object which can be easily consumed by any manner of destination clients.  JSON objects serialize to simple strings which have none of the issues of TTs.

Ha ha ha

Posted by Thomas Mercer-Hursh on 02-Jul-2014 16:08

It was not my intention to turn this into a big debate here, merely to note the issue and move on.

Posted by agent_008_nl on 03-Jul-2014 08:16

> It was not my intention to turn this into a big debate here, merely to note the issue and move on.

Ha ha ha

--

Kind regards,

Stefan Houtzager

Houtzager ICT consultancy & development

www.linkedin.com/in/stefanhoutzager

Posted by Tim Kuehn on 03-Jul-2014 08:53

[quote user="Thomas Mercer-Hursh"] It was not my intention to turn this into a big debate here, merely to note the issue and move on. [/quote] 

Ummm....no. 

I talk about a little project to OOize certain TT/PDS functionality, and you're all over my case about how I'm "wrong" to do so. Now in this thread you say TT an an Object is the "right" thing to do and doing it otherwise is wrong.... what are we to believe? 

Posted by Thomas Mercer-Hursh on 03-Jul-2014 09:36

Noting that one is asking the wrong question and that there is another way to think about the problem is something I frequently do.  I think that is appropriate and useful ... just like it was back in the early days of event driven programming when people kept asking about techniques to force people to stay in fields with bad data instead of letting them navigate the screen freely.   That doesn't mean that those who have a contrary position need to do anything more than note their position and we can all move on.  It is still the case that it was not my intent, then or now, to turn this into a protracted debate about what is right or wrong.  To be sure, that would be better in its own thread.  But, even given the existence of such a thread, I think it is right to point out the alternative in the context of specific questions like this one since people reading this thread may not read the "theoretical" one.

This thread is closed