BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

OPF and lifecycle of objects in and out the objectcache
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Gerard
Guest





PostPosted: Sat Jan 13, 2007 12:22 am    Post subject: OPF and lifecycle of objects in and out the objectcache Reply with quote



Hi all,

I'm building a OPF, and the OPF has a object cache wich keeps created or
retrieved objects in memory.
A retrieve operation goes like this:

See if the Id we ask for is in the cache.
If it's there
return the object.
Otherwise
Ask the storage layer for the object
If the object was retrieved from storage
Put it in the cache
Return the Object
Otherwise
Return Nil


As it is designed now, an object can only exist once in the cache, but
it can be referenced in many different places:
- Individual objects created by a call to a constructor Retrieve(ID)
method. e.g. aInvoice := TInvoice.Retrieve('1001')
- As a list element, from a ObjectList type attribute e.g.
aCustomer.Invoices[0] or Invoice.Items[2]
- As a list element from an independent list used to retrieve objects
with some specific criteria. e.g. aInvoiceList :=
TMyObjectList.Create(TInvoice, 'Total > 10000')
Lists are loaded from storage and then the cache is updated if needed.

I have a problem trying to figure how to manage explicit object freeing
in a efficient and clear way.
When an object is freed by a call to MyObject.Free, I cannot really free
it because it may be referenced in many places. But is keeping objects
in the cache forever (or at least until the cache is emptied) a good
solution?
If not, I guess I should have to implement some kind of reference counting?

I'd apreciate any thougths/experiences on this.

Regards, and have a nice weekend.

Gerard.
Back to top
Peter Morris [Droopy eyes
Guest





PostPosted: Sat Jan 13, 2007 1:47 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote



Hi Gerard

If you introduce the idea of having an ObjectReference class instead of
using direct references you could safely unload objects at any point you
like as long as you never free the ObjectReference. For example


PurchaseOrder.OrderLines[0].Object

OrderLine.PurchaseOrder.Object

The ObjectReference holds the information it needs to fetch the object
itself from the DB, when you ask for the Object it loads it, when the object
is unloaded its ObjectReference.Object is set to NIL.




--
--
Pete

Blessed are the geek, for they shall public class GeekEarth : Earth {}
====
Audio compression components, DIB graphics controls, ECO extensions,
FastStrings
http://www.droopyeyes.com
http://mrpmorris.blogspot.com
====
Back to top
Gerard
Guest





PostPosted: Sat Jan 13, 2007 2:34 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote



Hi Peter,

Quote:
If you introduce the idea of having an ObjectReference class instead of
using direct references you could safely unload objects at any point you
like as long as you never free the ObjectReference. For example

This is how I designed it. I have attributes for simple types like TIntegerAttribute, TStringAttribute... and TObjectReferenceAttribute and TObjectReferencesAttribute attributes for object and object lists references.
My concerns where:
- I should find a way to bypass the free method for objects or
else refrain from using it. If call aObject.free and that object is referenced elsewhere, I'll run into trouble.
- Otherwise, I should provide some alternative to free that does the real "free", to be called by the object cache when shutting down.
- I don't like the idea of a object cache that never stops growing .
Now I see that I should have keep some kind of mechanism in the object and object list attributes to know if the object or objectlist are really loaded, as they won't be loaded at first when the referencer object is loaded.

And to think that some people need sudokus when there are OPF's <g>

Gerard.
Back to top
Bob Dawson
Guest





PostPosted: Sat Jan 13, 2007 2:54 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

"Gerard" wrote
Quote:

A retrieve operation goes like this:

See if the Id we ask for is in the cache.
If it's there
return the object.
Otherwise
Ask the storage layer for the object
If the object was retrieved from storage
Put it in the cache
Return the Object
Otherwise
Return Nil

That's basically the way my system works.

Quote:
As it is designed now, an object can only exist once in the cache, but
it can be referenced in many different places:

I tend to refer to this as an 'instance singleton' pattern. There can be any
number of customers in existance, but only one global instance of
customer[custID]

Quote:
it because it may be referenced in many places. But is keeping objects
in the cache forever (or at least until the cache is emptied) a good
solution?

not in my view.

Quote:
If not, I guess I should have to implement some kind of reference
counting?


In addition to your Retrieve(ID) method, I supply a 'Release' method.

Refcounting is supplied by the business object cache. Essentially:

Quote:
If it's there
inc instance refcount
return the object.
Otherwise
Ask the storage layer for the object
If the object was retrieved from storage
Put it in the cache (refcount 0)
inc instance refcount
Return the Object
Otherwise
Return Nil

Calling free directly on a BO is not allowed.

The business object cache is a lazy loaded property of the persistence
portal: it is created automatically the first time a BO is created, and
destroyed automatically whenever its count drops to zero.

bobD
bobD
Back to top
Harley Pebley
Guest





PostPosted: Sat Jan 13, 2007 6:43 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Quote:
I'm building a OPF, and the OPF has a object cache wich keeps created
or retrieved objects in memory. ...

I have a problem trying to figure how to manage explicit object
freeing in a efficient and clear way. ... If
not, I guess I should have to implement some kind of reference
counting?

I'd apreciate any thougths/experiences on this.

Use interface rather than object references.

Regards,
Harley Pebley
www.skylark-software.com
Back to top
Guest






PostPosted: Sat Jan 13, 2007 7:03 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Hello Gerard,

What I have done is to reintroduce a Free method in order to take into
account the reference count mechanism and if the instance is no longer
referenced then I call the "real" free method:

TNKObject = class(TPersistent)
private
FRefCount: Integer;
procedure InternalFree;
procedure Release;
procedure AddRef;
public
procedure Free; reintroduce;
end;

procedure TNKObject.InternalFree;
begin
inherited Free;
end;

procedure TNKObject.Free;
begin
Release;
end;

procedure TNKObject.AddRef;
begin
BOCriticalSection.Acquire;
Inc(FRefCount);
BOCriticalSection.Release;
end;

procedure TNKObject.Release;
begin
if Self = nil then Exit;
Assert((FRefCount <> 0), Format('%s: RefCount<>0', [ClassName]));

BOCriticalSection.Acquire; // framework lock
Dec(FRefCount);
BOCriticalSection.Release;
if FRefCount = 0 then
InternalFree;
end;

One last thing, do not free your objects using FreeAndNil, instead make
your own BoFreeAndNil in order to call the properly reintroduced Free
method:

procedure BoFreeAndNil(var Obj);
var
Instance: TNKObject;
begin
Instance := TNKObject(Obj);
TNKObject(Instance) := nil;
Instance.Free;
end;

I hope it helps you.

Luis Solar.

Gerard ha escrito:

Quote:
Hi all,

I'm building a OPF, and the OPF has a object cache wich keeps created or
retrieved objects in memory.
A retrieve operation goes like this:

See if the Id we ask for is in the cache.
If it's there
return the object.
Otherwise
Ask the storage layer for the object
If the object was retrieved from storage
Put it in the cache
Return the Object
Otherwise
Return Nil


As it is designed now, an object can only exist once in the cache, but
it can be referenced in many different places:
- Individual objects created by a call to a constructor Retrieve(ID)
method. e.g. aInvoice := TInvoice.Retrieve('1001')
- As a list element, from a ObjectList type attribute e.g.
aCustomer.Invoices[0] or Invoice.Items[2]
- As a list element from an independent list used to retrieve objects
with some specific criteria. e.g. aInvoiceList :=
TMyObjectList.Create(TInvoice, 'Total > 10000')
Lists are loaded from storage and then the cache is updated if needed.

I have a problem trying to figure how to manage explicit object freeing
in a efficient and clear way.
When an object is freed by a call to MyObject.Free, I cannot really free
it because it may be referenced in many places. But is keeping objects
in the cache forever (or at least until the cache is emptied) a good
solution?
If not, I guess I should have to implement some kind of reference counting?

I'd apreciate any thougths/experiences on this.

Regards, and have a nice weekend.

Gerard.
Back to top
Harley Pebley
Guest





PostPosted: Sat Jan 13, 2007 3:10 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Quote:
What I have done is to reintroduce a Free method in order to take into
account the reference count mechanism and if the instance is no longer
referenced then I call the "real" free method:

Why not use this same technique only overriding destroy?
Then you don't have to worry about which Free method gets called (i.e.
the normal FreeAndNil can be used).

Quote:
...

procedure TNKObject.AddRef;
begin
BOCriticalSection.Acquire;
Inc(FRefCount);
BOCriticalSection.Release;
end;

1) You might want to think about putting protecting that release with a
try/finally block.

2) If all you're protecting is the ref count, why not use the
InterlockedInc/InterlockedDec and get rid of the critical section?

3) If you do use the critical section, I didn't see it declared in the
class which implies that it's global. Don't you want one per instance
rather than one per application?

Just some thoughts...
HTH,
Harley Pebley
www.skylark-software.com
Back to top
Peter Morris [Droopy eyes
Guest





PostPosted: Sat Jan 13, 2007 6:12 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Quote:
Use interface rather than object references.

Interfaces do not provide a very good form of garbage collection. All you
need is two instances referencing each other and they'll stay in memory
until the app closes.



--
--
Pete

Blessed are the geek, for they shall public class GeekEarth : Earth {}
====
Audio compression components, DIB graphics controls, ECO extensions,
FastStrings
http://www.droopyeyes.com
http://mrpmorris.blogspot.com
====
Back to top
Joao Morais
Guest





PostPosted: Sat Jan 13, 2007 7:08 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Gerard wrote:

Quote:
I have a problem trying to figure how to manage explicit object freeing
in a efficient and clear way.
When an object is freed by a call to MyObject.Free, I cannot really free
it because it may be referenced in many places. But is keeping objects
in the cache forever (or at least until the cache is emptied) a good
solution?
If not, I guess I should have to implement some kind of reference counting?

I'd apreciate any thougths/experiences on this.

I will describe how InstantObjects and PressObjects BOs manage reference
counting without use interfaces.

- When the object is created, a refcount variable is assigned to 1. When
it is retrieved from the cache, its refcount is incremented.

- Override the FreeInstance method and decrement refcount. If refcount
reached zero, call inherited FreeInstance.

- Reintroduce Destroy as a static method because a Free call will always
call the destructor even if the instance isn't destroyed. Create a
virtual Finalize method that is called before the inherited
FreeInstance, so your BOs can override it when necessary.

- Currently PressObjects doesn't implement a circular reference check in
order to avoid memory leakages, but InstantObjects implements it.

- You have also AddRef and Release that you can use to change reference
counting for any BO.

Using this approach you can manage object as if they don't implement
reference count, just use .Create, .Retrieve, .Free and you won't have
leakages or AVs.

HTH.

--
Joao Morais
Back to top
Joao Morais
Guest





PostPosted: Sat Jan 13, 2007 7:24 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Harley Pebley wrote:

Quote:
What I have done is to reintroduce a Free method in order to take into
account the reference count mechanism and if the instance is no longer
referenced then I call the "real" free method:

Why not use this same technique only overriding destroy?
Then you don't have to worry about which Free method gets called (i.e.
the normal FreeAndNil can be used).

The destroy method is just an event, you should override FreeInstance.

--
Joao Morais
Back to top
Harley Pebley
Guest





PostPosted: Sat Jan 13, 2007 11:30 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Quote:
Use interface rather than object references.

Interfaces do not provide a very good form of garbage collection.
All you need is two instances referencing each other and they'll stay
in memory until the app closes.

No doubt. But in my experience, it's better than what I understood to
be proposed by the OP.

Regards,
Harley Pebley
www.skylark-software.com
Back to top
Harley Pebley
Guest





PostPosted: Sat Jan 13, 2007 11:34 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Quote:
What I have done is to reintroduce a Free method in order to take
into >> account the reference count mechanism and if the instance is
no longer >> referenced then I call the "real" free method:

Why not use this same technique only overriding destroy?
Then you don't have to worry about which Free method gets called
(i.e. the normal FreeAndNil can be used).

The destroy method is just an event, you should override FreeInstance.

Huh? Destroy is the destructor that Free calls. Did you mean Destroy is
just one of possibly many destructors which might be called?

If I recall correctly, all destructors turn around and call
FreeInstance. In this case, I agree, FreeInstance is probably a better
method to override.

Regards,
Harley Pebley
www.skylark-software.com
Back to top
Joao Morais
Guest





PostPosted: Sun Jan 14, 2007 5:39 am    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Harley Pebley wrote:

Quote:
Why not use this same technique only overriding destroy?
Then you don't have to worry about which Free method gets called
(i.e. the normal FreeAndNil can be used).
The destroy method is just an event, you should override FreeInstance.

Huh? Destroy is the destructor that Free calls. Did you mean Destroy is
just one of possibly many destructors which might be called?

I meant that override Destroy in order to skip the instance destruction
does not work.

--
Joao Morais
Back to top
Gerard
Guest





PostPosted: Sun Jan 14, 2007 5:11 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

Thanks all for your suggestions and feedback.
I have much clearer idea now of what to do and how to do it.

Regards,

Gerard.
Back to top
Bob Dawson
Guest





PostPosted: Sun Jan 14, 2007 10:00 pm    Post subject: Re: OPF and lifecycle of objects in and out the objectcache Reply with quote

<lsolart (AT) gmail (DOT) com> wrote
Quote:

What I have done is to reintroduce a Free method

Why I didn't go down the Free/Destroy/FreeInstance method is that I think it
conflates the nature of the object and the access pattern it happens to be
participating in. That is, ref-counting is really a consequence of the
centralized object cache and instance-singleton pattern, not anything
inherent to the BO itself. So ref-counting doesn't doesn't belong there, but
in the caching mechanism.

Why does that matter? Suppose you decide you want to allow duplicate copies
of an instance for a specific purpose: a snapshot copy. A typical use for
such a thing would be gathering a group of objects and using them as a basis
for a report. In this case you want snapshot copies of the reported objects,
and you want them isolated: nothing that happens on another form should
change a reported object once it's been added to the report, and nothing
that the report does should be visible to the rest of the program.

If the BOs themselves are hard wired to the running objects cache system and
do their own reference counting, then this kind of 'take an object offline'
scenario becomes either impossible, or much harder than it should be.

Keeping the BO's a bit more isolated from the cache architecture allows you
to provide multiple access scenarios:

bobD
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.