Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » ResourceImpl.unload triggers loading
ResourceImpl.unload triggers loading [message #1278442] Thu, 27 March 2014 10:47 Go to next message
Caspar D. is currently offline Caspar D.Friend
Messages: 35
Registered: July 2009
Member
I have a custom resource implementation that extends from ResourceImpl and is backed by an EStore implementation that fetches objects on demand. Unloading works okay through my override of #doUnload, but there's one thing that's not so pretty: ResourceImpl#unload calls #getContents and passes the result into the constructor of BasicEList.FastCompare, which iterates over the list. This inevitably triggers my demand-loading mechanism to get the root objects. So I'm faced with the situation that unloading a resource triggers loading. Since #unload is declared final, there is no way (AFAICS) to do anything about this.

Is there a better/different way of doing this that would avoid this problem?
Re: ResourceImpl.unload triggers loading [message #1278453 is a reply to message #1278442] Thu, 27 March 2014 11:00 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Caspar,

Comments below.

On 27/03/2014 11:47 AM, Caspar De Groot wrote:
> I have a custom resource implementation that extends from ResourceImpl
> and is backed by an EStore implementation that fetches objects on
> demand. Unloading works okay through my override of #doUnload, but
> there's one thing that's not so pretty: ResourceImpl#unload calls
> #getContents and passes the result into the constructor of
> BasicEList.FastCompare, which iterates over the list. This inevitably
> triggers my demand-loading mechanism to get the root objects.
How would you otherwise get the objects to unload?
> So I'm faced with the situation that unloading a resource triggers
> loading. Since #unload is declared final, there is no way (AFAICS) to
> do anything about this.
>
> Is there a better/different way of doing this that would avoid this
> problem?
Would a protected getUnloadingContents method help?


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: ResourceImpl.unload triggers loading [message #1278485 is a reply to message #1278453] Thu, 27 March 2014 11:51 Go to previous messageGo to next message
Caspar D. is currently offline Caspar D.Friend
Messages: 35
Registered: July 2009
Member
Ed Merks wrote on Thu, 27 March 2014 07:00

How would you otherwise get the objects to unload?


Not sure if I understand your question, but perhaps this clarifies: my EStore implementation knows which objects have been loaded, and my override of ResourceImpl#doUnload tells the store to discard those objects. But it's not a given that the roots were ever loaded: the app using my solution might only request some non-root objects, which makes it undesirable that unloading requires the roots to be fetched.

Quote:
Would a protected getUnloadingContents method help?


As a replacement for the unloadingContents field? Yes, but perhaps not in the way that you have in mind. I would just override it to return null or an empty collection, so that I avoid the loading of the roots. I can't use it to return my loaded objects because the base implementation of #doUnload does a tree-walk on whatever that collection contains. I don't want a tree-walk at all; I want to iterate only over the subset of objects I have loaded.

I think it'd be better to have something like a protected getUnloadingContentsIterator returning a regular Iterator (not a TreeIterator), to replace the call to getAllProperContents at the top of ResourceImpl.doUnload.

Thanks!
Re: ResourceImpl.unload triggers loading [message #1278569 is a reply to message #1278485] Thu, 27 March 2014 14:15 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Caspar,

Comments below.

On 27/03/2014 12:51 PM, Caspar D. wrote:
> Ed Merks wrote on Thu, 27 March 2014 07:00
>> How would you otherwise get the objects to unload?
>
>
> Not sure if I understand your question, but perhaps this clarifies: my
> EStore implementation knows which objects have been loaded, and my
> override of ResourceImpl#doUnload tells the store to discard those
> objects.
I see.
> But it's not a given that the roots were ever loaded: the app using my
> solution might only request some non-root objects, which makes it
> undesirable that unloading requires the roots to be fetched.
>
> Quote:
>> Would a protected getUnloadingContents method help?
>
>
> As a replacement for the unloadingContents field?
Basically to factor out the code that's making a copy of the list. You
won't be affected by any of the places where the unloadingContents list
is used elsewhere?
> Yes, but perhaps not in the way that you have in mind.
I just want to enable you in a way that's not disruptive to anyone else...
> I would just override it to return null or an empty collection, so
> that I avoid the loading of the roots. I can't use it to return my
> loaded objects because the base implementation of #doUnload does a
> tree-walk on whatever that collection contains. I don't want a
> tree-walk at all; I want to iterate only over the subset of objects I
> have loaded.
So you could return null and completely override doUnload, keeping any
parts you still need. You still call unloaded for each object?
>
> I think it'd be better to have something like a protected
> getUnloadingContentsIterator returning a regular Iterator (not a
> TreeIterator), to replace the call to getAllProperContents at the top
> of ResourceImpl.doUnload.
You could get by with just your own implementation. Likely you don't
need to clear the contents list...
>
> Thanks!
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: ResourceImpl.unload triggers loading [message #1279043 is a reply to message #1278569] Fri, 28 March 2014 06:52 Go to previous messageGo to next message
Caspar D. is currently offline Caspar D.Friend
Messages: 35
Registered: July 2009
Member
>>> Would a protected getUnloadingContents method help?
>>
>> As a replacement for the unloadingContents field?
>
> Basically to factor out the code that's making a copy of the list. You
> won't be affected by any of the places where the unloadingContents list
> is used elsewhere?

No, I don't think so.

> So you could return null and completely override doUnload, keeping any
> parts you still need.

Yes.

> You still call unloaded for each object?

No. I clear the adapters in my EStore implementation, and as for the
setting of the proxy URI's, I currently don't need that.

> You could get by with just your own implementation. Likely you don't
> need to clear the contents list...

Correct. In fact my first reason for overriding doUnload was to
avoid the contents.clear() call, as it invokes #detach for every
object, which is interpreted as a deletion by my store.

Thanks again

--
Caspar

[Updated on: Fri, 28 March 2014 06:54]

Report message to a moderator

Re: ResourceImpl.unload triggers loading [message #1279675 is a reply to message #1279043] Sat, 29 March 2014 04:02 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Caspar,

Comments below.

On 28/03/2014 7:52 AM, Caspar D. wrote:
>>>> Would a protected getUnloadingContents method help?
>>>
>>> As a replacement for the unloadingContents field?
>>
>> Basically to factor out the code that's making a copy of the list.
>> You won't be affected by any of the places where the
>> unloadingContents list is used elsewhere?
>
> No, I don't think so.
So you don't need to compute proxy URIs...
>
>> So you could return null and completely override doUnload, keeping
>> any parts you still need.
>
> Yes.
>
>> You still call unloaded for each object?
>
> No. I clear the adapters in my EStore implementation, and as for the
> setting of the proxy URI's, I currently don't need that.
If anything else is referencing those objects they'd be broken?
>
>> You could get by with just your own implementation. Likely you don't
>> need to clear the contents list...
>
> Correct. In fact my first reason for overriding doUnload was to
> avoid the contents.clear() call, as it invokes #detach for every
> object which is interpreted as a deletion by my store.
I see.
>
> Thanks again
>
> --
> Caspar
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: ResourceImpl.unload triggers loading [message #1280991 is a reply to message #1279675] Mon, 31 March 2014 07:39 Go to previous messageGo to next message
Caspar D. is currently offline Caspar D.Friend
Messages: 35
Registered: July 2009
Member
>So you don't need to compute proxy URIs...

>If anything else is referencing those objects they'd be broken?

Currently, yes. I'm not against setting the proxy URI's. It's just
that for my intended client resolving objects after an #unload
isn't important at this stage.

I wouldn't mind having #unloaded called for all objects that are
*really* loaded. I just don't want all the roots to get fetched,
nor do I want all the contents to get tree-walked over. So a
protected method to compute this collection (i.e. not just the
roots but everything that should be iterated over) still seems
like the solution to me.

Thanks
--
Caspar
Re: ResourceImpl.unload triggers loading [message #1281605 is a reply to message #1280991] Tue, 01 April 2014 04:51 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Caspar,

Comments below.

On 31/03/2014 9:39 AM, Caspar D. wrote:
>> So you don't need to compute proxy URIs...
>
>> If anything else is referencing those objects they'd be broken?
>
> Currently, yes.
Hmmm...
> I'm not against setting the proxy URI's.
Setting the proxy URIs currently doesn't rely on unloadingContents
containing the list of root objects
> It's just
> that for my intended client resolving objects after an #unload
> isn't important at this stage.
What if it becomes important at a later stage?
> I wouldn't mind having #unloaded called for all objects that are
> *really* loaded. I just don't want all the roots to get fetched,
> nor do I want all the contents to get tree-walked over.
That makes sense because if an object has never been seen by anything in
the JVM, it essentially don't exist...
> So a
> protected method to compute this collection (i.e. not just the
> roots but everything that should be iterated over) still seems
> like the solution to me.
Yes. I'm just concerned about the overall consistency. E.g., if I have
called resource.getContents and have iterated over the contents and have
added an adapter to observe how the resource's contents change, I do
expect an unload call to inform me that the resource contents are
changed. But it seems that won't happen. Also, if I have references to
objects in the resource, I expect them to become proxies, which also
doesn't happen. So general aspects of the framework will behave poorly.

So even a missing call to "clear" of the contents already creates an
inconsistency in the framework. It's hard for me to motivate enabling
inconsistencies... Does your resource contain a great many objects at
the root? I think for consistency you minimally need to inform
observers that you've removed objects from the resource that may have
been observed to be in the root of resource, and you need to convert to
proxies any object that has been observed to be in the root of the
resource or contained somewhere therein... So I imagine a consistent
implementation would return a list of the root objects and you could
specialize the content traversal to traverse every object ever made
visible to a client.
>
> Thanks
> --
> Caspar
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: ResourceImpl.unload triggers loading [message #1281795 is a reply to message #1281605] Tue, 01 April 2014 11:14 Go to previous messageGo to next message
Caspar D. is currently offline Caspar D.Friend
Messages: 35
Registered: July 2009
Member
Hi Ed,

I understand that you don't want to enable inconsistencies, but
skipping some or all of the actions performed in #doUnload (e.g.
clearing the contents and setting the proxyURIs) is already
possible since this method isn't marked final. I don't see how
having a protected getIteratorOverUnloadableObjects (which would
get called at the top of #doUnload) would enable inconsistencies
more than they already are.

> I think for consistency you minimally need to inform observers
> that you've removed objects from the resource that may have been
> observed to be in the root of resource,

The trouble with the removal of root objects is that it invokes
the detachedHelper, my implementation of which interprets a detach
as an intentional operation on the data (which it persists). The
detachedHelper has no way of knowing the difference between a
"real detach" and a "detach because of unloading".

Anyway, the consequences of my implementation choices are my own
of course, but it seems no (additional) inconsistencies would
arise if I could avoid the getContents call, since my implementation
already doesn't use the result.

Regards

--
Caspar
Re: ResourceImpl.unload triggers loading [message #1281815 is a reply to message #1281795] Tue, 01 April 2014 11:50 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Caspar,

Comments below.

On 01/04/2014 1:14 PM, Caspar D. wrote:
> Hi Ed,
> I understand that you don't want to enable inconsistencies, but
> skipping some or all of the actions performed in #doUnload (e.g.
> clearing the contents and setting the proxyURIs) is already
> possible since this method isn't marked final. I don't see how
> having a protected getIteratorOverUnloadableObjects (which would
> get called at the top of #doUnload) would enable inconsistencies
> more than they already are.
That's true.
>> I think for consistency you minimally need to inform observers
>> that you've removed objects from the resource that may have been
>> observed to be in the root of resource,
>
> The trouble with the removal of root objects is that it invokes
> the detachedHelper, my implementation of which interprets a detach
> as an intentional operation on the data (which it persists).
It could look at the unloadContents being non-null not to do that...
> The
> detachedHelper has no way of knowing the difference between a
> "real detach" and a "detach because of unloading".
if (unloadingContents != null) // then you're in the process of unloading...
>
> Anyway, the consequences of my implementation choices are my own
> of course, but it seems no (additional) inconsistencies would
> arise if I could avoid the getContents call, since my implementation
> already doesn't use the result.
I'm just being picky, and hoping to help you find the best way to be
fully consistent and then enabling that.

For example, you probably know which objects you've yielded via the
Resource.getContents(). E.g., if someone has called
Resource.getContents().size, have you loaded all the objects? If
someone calls Resource.getContents(n), have you loaded all the objects
up until n? Do you have a specialized contents list for the resource?
To my thinking, that's probably the most problematic area to address,
but without knowing your implementation and how best to produce a
general solution I can only guess. E.g., I imagine if you got the
notification on getContents working consistently, elsewhere you could
iterate over the "known loaded objects" and process only those in the
usual way.

I can certainly change the code to this if that makes you happy and you
have no further interest in keeping the rest of the framework working
consistently:

/*
* Javadoc copied from interface.
*/
public final void unload()
{
if (isLoaded)
{
unloadingContents = getUnloadingContents();
Notification notification = setLoaded(false);
try
{
doUnload();
}
finally
{
unloadingContents = null;
if (notification != null)
{
eNotify(notification);
}
setTimeStamp(URIConverter.NULL_TIME_STAMP);
}
}
}

protected List<EObject> getUnloadingContents()
{
return new BasicEList.FastCompare<EObject>(getContents());
}

But perhaps there are other changes that would be quite helpful, e.g.,
maybe certain calls to getAllProperContents could delegate to a method
that returns an iterator where you could factor in your logic to visit
the actually loaded objects... What do you use for your URI fragments?
>
> Regards
>
> --
> Caspar
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:difference between using XMLResource.OPTION_BINARY and BinaryResourceImpl
Next Topic:[oomph] change directory of bundle pool
Goto Forum:
  


Current Time: Thu Apr 18 23:12:58 GMT 2024

Powered by FUDForum. Page generated in 0.02657 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top