Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update asset scheme #109

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
Open

Conversation

pollend
Copy link
Member

@pollend pollend commented Apr 26, 2021

this changes how assets work with the assetmanager and attempts to address some problems.

  1. for transient assets the current scheme will slowly leak weak pointers since they are not properly removed from the multimap.
  2. there is now just a single map from a resource urn to the start of a chain of assets. (non-transient assets use soft-reference and transient assets use a weakreference but weak references use a strong reference so the non-transient asset so it's not disposed unless all transient assets have been disposed in the chain.
  • the non-transient asset is always placed first and all transient assets use a weak reference
  • each asset is chained from the beginning forward as new assets are added they are placed at the beginning of the chain unless if its a non-transient asset then it skips the first entry

image

Copy link
Member

@immortius immortius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this request needs work. I'm concerned firstly with the scope of the changes. I think it is a bit overdone - in particular I do not believe a node based linked list system needed to be developed, as simpler tweaks around the existing implementation would have enabled the improvements. Also I'm concerned some changes introduce bugs or break encapsulation. Also some style issues.

I do agree with:

  • Changing normal assets to be kept via soft references
  • Cleaning up null weak references from the instance asset map
  • Adding tracking of parent urn to the asset references to enable the above

@@ -642,13 +717,14 @@ public String toString() {
}
}

private static final class AssetReference<T> extends PhantomReference<T> {
public final class AssetReference<T extends Asset<?>> extends PhantomReference<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this public now? Why is it no longer static? There's no reason other classes should be doing anything with an asset reference. And AssetReference is not doing anything with it's parent asset type?

@pollend
Copy link
Member Author

pollend commented Apr 26, 2021

Overall, this request needs work. I'm concerned firstly with the scope of the changes. I think it is a bit overdone - in particular I do not believe a node based linked list system needed to be developed, as simpler tweaks around the existing implementation would have enabled the improvements. Also I'm concerned some changes introduce bugs or break encapsulation. Also some style issues.

I do agree with:

* Changing normal assets to be kept via soft references

* Cleaning up null weak references from the instance asset map

* Adding tracking of parent urn to the asset references to enable the above 

One of the benefits with this scheme is it decouples a lot of the book keeping from AssetType. Assets can clone and insert a reference into the chain without depending on or notifying assetType of the change. at most you would just need to introduce a way to lock the urn which isn't too hard to add to the current code. an AssetType would just manage the bookkeeping and clean up references as they go stale. The implementation could be cleaned up quite a bit since there is a large amount of book keeping with the code I added. The PR is pretty rough since the implementation is quite a bit more complicated.

@pollend pollend requested a review from immortius May 2, 2021 23:32
@pollend
Copy link
Member Author

pollend commented May 2, 2021

@immortius so I think this is a lot simpler then the original system. I decoupled the ownership of instanced assets from assetTypes. so assetTypes now only track non instanced assets. assets that create instances will now push it to a linked list. reloading just follows the chain of instanced assets and since each instance also has a strong link back to the parent asset then that resource is only held on as long as instanced assets are still valid. if a parent becomes invalid then all instanced assets should become invalid as well :D.

@pollend
Copy link
Member Author

pollend commented May 8, 2021

final synchronized Optional<? extends Asset<T>> createCopy(ResourceUrn copyUrn) {
Preconditions.checkState(!disposed);
return doCreateCopy(copyUrn, assetType);
public final Asset<T> getNormalAsset() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a javadoc to this method (all public methods should have javadoc to assist a user.
Not clear from the name what this does - what makes an asset "normal"? I might suggest getArchetype() or something like that, not sure if that adds clarity though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pollend I think it's still a bit unclear what "the normal type" here is 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getConcreteAsset doesn't really make this clearer to me.
please add a comment in code that explains what characterizes an asset as "concrete"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted it back to normal asset and updated the javadocs.

}
}

protected Iterable<WeakReference<Asset<T>>> instances() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be private/what reason is there for implementors to override this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or call it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pollend I think this question was not answered, was it? I see that you made it final, but why does it need to be on protected level?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pollend this question is still open

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to access all the list of instances from within the asset.

Reference<T> reference = loadedAssets.get(target);
Asset<U> current = reference.get();
if(current != null && current.isDisposed() && Iterables.isEmpty(current.instances())) {
logger.warn("non instanced asset is disposed with instances. instances will become orphaned.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably would be cleaner to dispose the children when the parent is disposed. But maybe for a future PR.

loadedAssets.remove(target);
return;
}
current.cleanup();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line probably is unreachable without an asset being loaded fresh into the urn in the meantime. Which I guess is possible through the onAssetDisposed pathway, since it isn't synchronized. Not sure it is a meaningful action regardless.

Comment on lines 269 to 273
void onAssetDisposed(Asset<U> asset) {
if (asset.getUrn().isInstance()) {
instanceAssets.get(asset.getUrn()).remove(new WeakReference<>(assetClass.cast(asset)));
} else {
loadedAssets.remove(asset.getUrn());
if (!asset.getUrn().isInstance()) {
disposeAsset(asset.getUrn());
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immortius I don't think we need this onAssetDisposed call anymore. looks like the asset is already managed in the processDisposal call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

Successfully merging this pull request may close these issues.

None yet

3 participants