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

Cache dependencies parsed from each individual import #4568

Merged
merged 1 commit into from Aug 31, 2018

Conversation

Legioth
Copy link
Member

@Legioth Legioth commented Aug 30, 2018

Previously, dependency parsing results were only cached per component
class. This means that if multiple components use the same import, that
import would have been parsed multiple times.

This patch adds a separate cache layer that keeps track of the imports
from individual files, and then traverses that cache to collect all
reachable imports.

Reduces total TTFB for the first view in Beverage Buddy from 1.2 to 0.6
seconds and from 1.1 to 0.3 seconds for opening the dialog.

Related to #4532.


This change is Reviewable

@marcushellberg
Copy link
Member

What is the impact of this cache on session size? Or is it a shared cache for the entire application?

@Legioth
Copy link
Member Author

Legioth commented Aug 30, 2018

The cache is shared for the entire application (field in VaadinService), so it shouldn't be an issue.

cache.put(node, dependencies);

synchronized (placeholder) {
placeholder.notifyAll();
Copy link
Collaborator

Choose a reason for hiding this comment

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

MAJOR Naked notify in com.vaadin.flow.component.internal.DependencyTreeCache.getOrParseDependencies(Object) rule


private Collection<T> waitForDependencies(T node, Object placeholder)
throws InterruptedException {
synchronized (placeholder) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

MAJOR "placeholder" is a method parameter, and should not be used for synchronization. rule

* @author Vaadin Ltd
* @since 1.0
*
*/
@Deprecated
public class HtmlDependencyParser implements Serializable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

INFO Do not forget to remove this deprecated code someday. rule


public MockParser addResult(String path, int duration,
String... dependencies) {
return addResult(path, () -> Thread.sleep(duration), dependencies);
Copy link
Collaborator

Choose a reason for hiding this comment

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

MAJOR Remove this use of "Thread.sleep()". rule

Copy link
Contributor

@caalador caalador left a comment

Choose a reason for hiding this comment

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

Reviewed 11 of 11 files at r1.
Reviewable status: 8 unresolved discussions, 0 of 1 LGTMs obtained


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 175 at r1 (raw file):

     */
    public void clear() {
        cache.clear();

Should we for clearing keep track of parsing instances and then wait for any to complete before clearing or just have them stop before clearing?

Previously, dependency parsing results were only cached per component
class. This means that if multiple components use the same import, that
import would have been parsed multiple times.

This patch adds a separate cache layer that keeps track of the imports
from individual files, and then traverses that cache to collect all
reachable imports.

Reduces total TTFB for the first view in Beverage Buddy from 1.2 to 0.6
seconds and from 1.1 to 0.3 seconds for opening the dialog.

Related to #4532.
Copy link
Member Author

@Legioth Legioth left a comment

Choose a reason for hiding this comment

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

Dismissed @vaadin-bot from a discussion.
Reviewable status: 7 unresolved discussions, 0 of 1 LGTMs obtained


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 81 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MAJOR Either re-interrupt this method or rethrow the "InterruptedException". rule

Done.


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 82 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MAJOR Define and throw a dedicated exception instead of using a generic one. rule

Anyone want to suggest what to throw, or should we just ignore sonar here?


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 114 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MAJOR Naked notify in com.vaadin.flow.component.internal.DependencyTreeCache.getOrParseDependencies(Object) rule

Nope. The observable effect is in the cache map.


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 130 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MAJOR "placeholder" is a method parameter, and should not be used for synchronization. rule

Nope.


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 175 at r1 (raw file):

Previously, caalador wrote…

Should we for clearing keep track of parsing instances and then wait for any to complete before clearing or just have them stop before clearing?

I don't think that would be worthwhile. The main reason for clearing this cache is if the file contents have been changed. In that situation, I'd say that it's quite fine that any processing done during the change will get potentially inconsistent results (since that's also what they'd get without the cache), as long as any new processing won't see any signs of the old file contents.


flow-server/src/main/java/com/vaadin/flow/component/internal/HtmlImportParser.java, line 108 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MINOR Move the "import" string literal on the left side of this string comparison. rule

Done.


flow-server/src/test/java/com/vaadin/flow/component/internal/DependencyTreeCacheTest.java, line 178 at r1 (raw file):

Previously, vaadin-bot (Vaadin Bot) wrote…

MAJOR Remove this use of "Thread.sleep()". rule

Nope.

// Restore interrupted state
Thread.currentThread().interrupt();

throw new RuntimeException(
Copy link
Collaborator

Choose a reason for hiding this comment

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

MAJOR Define and throw a dedicated exception instead of using a generic one. rule

@vaadin-bot
Copy link
Collaborator

SonarQube analysis reported 19 issues

  • CRITICAL 4 critical
  • MAJOR 10 major
  • MINOR 3 minor
  • INFO 2 info

Watch the comments in this conversation to review them.

Top 10 extra issues

Note: The following issues were found on lines that were not modified in the pull request. Because these issues can't be reported as line comments, they are summarized here:

  1. CRITICAL VaadinService.java#L2089: First sentence of Javadoc is incomplete (period is missing) or not present. rule
  2. CRITICAL VaadinService.java#L2123: First sentence of Javadoc is incomplete (period is missing) or not present. rule
  3. CRITICAL VaadinService.java#L2135: First sentence of Javadoc is incomplete (period is missing) or not present. rule
  4. CRITICAL VaadinService.java#L2147: First sentence of Javadoc is incomplete (period is missing) or not present. rule
  5. MAJOR ClassesSerializableTest.java#L166: Define and throw a dedicated exception instead of using a generic one. rule
  6. MAJOR ClassesSerializableTest.java#L291: Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed. rule
  7. MAJOR ClassesSerializableTest.java#L291: Define and throw a dedicated exception instead of using a generic one. rule
  8. MAJOR ClassesSerializableTest.java#L305: Reduce the total number of break and continue statements in this loop to use at most one. rule
  9. MAJOR ClassesSerializableTest.java#L333: This block of commented-out lines of code should be removed. rule
  10. MAJOR ClassesSerializableTest.java#L434: Use the built-in formatting to construct this argument. rule

Copy link
Contributor

@caalador caalador left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 2 of 2 files at r2.
Dismissed @vaadin-bot from 5 discussions.
Reviewable status: 5 unresolved discussions, 0 of 1 LGTMs obtained, and 1 stale


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 82 at r1 (raw file):

Previously, Legioth (Leif Åstrand) wrote…

Anyone want to suggest what to throw, or should we just ignore sonar here?

Feels like a ignore. Can't really come up with any descriptive exception name.


flow-server/src/main/java/com/vaadin/flow/component/internal/DependencyTreeCache.java, line 175 at r1 (raw file):

Previously, Legioth (Leif Åstrand) wrote…

I don't think that would be worthwhile. The main reason for clearing this cache is if the file contents have been changed. In that situation, I'd say that it's quite fine that any processing done during the change will get potentially inconsistent results (since that's also what they'd get without the cache), as long as any new processing won't see any signs of the old file contents.

👍

Copy link
Contributor

@caalador caalador left a comment

Choose a reason for hiding this comment

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

Dismissed @vaadin-bot from 2 discussions.
Reviewable status: 3 unresolved discussions, 1 of 1 LGTMs obtained

Copy link
Contributor

@caalador caalador left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! all discussions resolved, 1 of 1 LGTMs obtained

@caalador caalador merged commit 4a2c09b into master Aug 31, 2018
@caalador caalador deleted the dependencyTreeCache branch August 31, 2018 11:50
@SomeoneToIgnore SomeoneToIgnore added this to the 1.1.0.beta3 milestone Sep 3, 2018
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.

None yet

5 participants