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

add cache #4

Merged
merged 8 commits into from
Mar 28, 2024
Merged

add cache #4

merged 8 commits into from
Mar 28, 2024

Conversation

jamesward
Copy link
Member

Note that I wanted to preserve a way to use the locator statically so there is now a WebJarVersionLocator.DEFAULT for that.

@jamesward jamesward mentioned this pull request Mar 22, 2024
Copy link

@dsyer dsyer left a comment

Choose a reason for hiding this comment

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

Kind of OK by me. See comments.

src/main/java/org/webjars/WebJarVersionLocator.java Outdated Show resolved Hide resolved
src/main/java/org/webjars/WebJarVersionLocator.java Outdated Show resolved Hide resolved
@jamesward
Copy link
Member Author

Thanks @dsyer for the review!

@sdeleuze
Copy link

sdeleuze commented Mar 25, 2024

I can live with it, but I am not a big fan of the DEFAULT static instance:

  • I don't think WebJarAssetLocator from webjars-locator-core had one
  • I expect a lot of users just missing it and using new WebJarVersionLocator() leading to 2 instances created with 1 not used
  • If we are afraid users doing new WebJarVersionLocator() for each request, we could maybe just remove the static field and document this properly in the README (like webjars-locator-core does) and in the Javadoc.

Otherwise looks to to me.

@jamesward
Copy link
Member Author

Thanks @sdeleuze. Yeah, my concerns were that'd it is too easy to create a new cache on each usage. I'm not sure if there is a better design which has a static default and a way to override it. Any typical patterns for this?

@sdeleuze
Copy link

I don't think there is a good "self-contained" way to do that, by design. But I am not sure the situation is different than WebJarAssetLocator which had heavy resource scanning at initialization. I would even say that the cost of a misuse is lower now.

My recommandation would be to only provide the constructor, without the static field, and document clearly on both Javadoc and README that:

  • WebJarVersionLocator is thread-safe
  • That a single instance (singleton) is expected to be created, either via a static field (a code sample showing a WebJarVersionLocator static field on user class can be provided) or via other mechanism like dependency injection.

This is also what is done for very popular dependency of the ecosystem like Jackson ObjectMapper.

@jamesward
Copy link
Member Author

I guess in Java that is the best we can do. :) I'll get those changes done today.

@jamesward
Copy link
Member Author

Changes are in. LMKWYT. Thanks!

@sdeleuze
Copy link

sdeleuze commented Mar 27, 2024

Awesome, looks good to me for the singleton removal.

The only remaining ask would be to make PROPERTIES_ROOT, NPM, PLAIN and POM_PROPERTIES static like what you did for WEBJARS_PATH_PREFIX (I think this was the spirit of @dsyer review as he mentioned "These could (should) still be static, right?" even if I was also confused by the fact the feedback in the code review was just on WEBJARS_PATH_PREFIX).

@jamesward
Copy link
Member Author

Cool. I've changed that. And what about:

private final ClassLoader LOADER = WebJarVersionLocator.class.getClassLoader();

Should it be static as well?

@sdeleuze
Copy link

Indeed it can be static as well.

@jamesward jamesward merged commit 27d8ceb into main Mar 28, 2024
2 checks passed
@vpavic
Copy link

vpavic commented Apr 22, 2024

@jamesward do you really anticipate that someone would want to use a custom cache implementation with WebJarVersionLocator?

It seems to me that caching can easily be an internal implementation detail, which then removes the need for WebJarCache abstraction and additionally allows your cache interactions to be atomic (by leveraging ConcurrentHashMap#computeIfAbsent).

@jamesward
Copy link
Member Author

Good point. If the Spring's usage doesn't foresee plugging in a custom cache then we could make it internal. Question on ConcurrentHashMap#computeIfAbsent - I imagine that a common situation using the locator would be that multiple requests for the same WebJar will come in at the same time (due to parallel loading from the browser). Would computeIfAbsent essentially do a lock so that only 1 of the concurrent requests would do the actual lookup?
cc @sdeleuze

@sdeleuze
Copy link

sdeleuze commented Apr 23, 2024

There is indeed likely something to refine here.

Would computeIfAbsent essentially do a lock so that only 1 of the concurrent requests would do the actual lookup?
For the initial request yes, see https://stackoverflow.com/a/10589196/1092077 for more details.

I created a dedicated new issue, let's maybe continue the discussion there: #8

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

Successfully merging this pull request may close these issues.

4 participants