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

PTV-1620 - fix browser freeze and crash when rendering large heatmaps #3116

Merged
merged 7 commits into from
Oct 25, 2022

Conversation

eapearson
Copy link
Contributor

@eapearson eapearson commented Oct 20, 2022

Description of PR purpose/changes

This change fixes PTV-1620, which reflects a public ticket that cited two issues when viewing a FeatureCluster object

  • a data-tables error
  • browser freezing and/or crashing

The data-tables error was due to a missing field which was not supplied with a default value; data-tables does not like undefined values. This issue was fixed separately.

The changes in this PR fix the browser freezing and crashing issue. That problem is due to the creation of a heatmap when the number of features is greater than about 200. The heatmap is grows by N², where N is the number of features. The processing of the data for the heatmap beyond 200 features will begin to consume several seconds, and at a certain point may cause the browser to crash or report an unresponsive tab.

It is notable that the affected widget, kbaseExpressionPairwiseCorrelation, already restricted the display of a heatmap with over 50 features. With over 50 features in a cluster, it provides a link for downloading the heatmap, which is hidden.

However, it placed no limits on the creation of the heatmap. It is the creation of the heatmap that consumes a great deal of cpu and memory, leading to unresponsiveness and crashing.

This set of changes focuses on addressing this issue, but also:

  • corrects and improves some code issues within the same file.
  • fixes an unreported issue with downloading the heatmap (wherein the second and subsequent download attempts will fail.)

There are several UI and code issues that will be addressed by a subsequent PR, affecting quite a few additional files.

Jira Ticket / Issue

Testing Instructions

Unit tests have been added.

  • Tests pass locally and in GitHub Actions
  • Changes available by spinning up a local narrative and navigating to X to see Y

Dev Checklist:

  • My code follows the guidelines at https://sites.google.com/lbl.gov/trussresources/home?authuser=0
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • [-] I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • (JavaScript) I have run Prettier and ESLint on changed code manually or with a git precommit hook
  • [-] (Python) I have run Black and Flake8 on changed Python code manually or with a git precommit hook
  • [-] Any dependent changes have been merged and published in downstream modules

Updating Version and Release Notes (if applicable)

@eapearson eapearson changed the title fix browser freeze and crash when rendering large heatmaps PTV-1620 - fix browser freeze and crash when rendering large heatmaps Oct 20, 2022
@eapearson
Copy link
Contributor Author

The code analysis failure is due to the invocation of a kbwidget using "new" -- the widget itself is not stored, so the "bug" is constructing an object without using it. Just the weirdness of kbwidget freaking out code analysis.

@eapearson eapearson requested a review from briehl October 20, 2022 14:29
@codecov
Copy link

codecov bot commented Oct 20, 2022

Codecov Report

Merging #3116 (fa0491e) into develop (a198ed2) will not change coverage.
The diff coverage is n/a.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #3116   +/-   ##
========================================
  Coverage    73.37%   73.37%           
========================================
  Files           36       36           
  Lines         3917     3917           
========================================
  Hits          2874     2874           
  Misses        1043     1043           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 21d9e03...fa0491e. Read the comment docs.

@eapearson
Copy link
Contributor Author

I'll have a closer look at the failing test ... it works locally.

@eapearson
Copy link
Contributor Author

Added ticket https://kbase-jira.atlassian.net/browse/PTV-1844 because I wanted to have screenshots of each of the widget states.

It may be reviewed directly by building off this PR or the branch and viewing a FeatureClusters object, e.g. as output from "Cluster Expression Data - K-Means"

Copy link
Member

@briehl briehl left a comment

Choose a reason for hiding this comment

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

Just some minor test file tweaks, but looks great. Thanks for doing this!

* @param {int} duration
* @returns {Promise<void>}
*/
function waitFor(duration) {
Copy link
Member

Choose a reason for hiding this comment

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

This is effectively a duplicate of https://github.com/kbase/narrative/blob/develop/test/unit/testUtil.js#L63 and should just use that one.

The tryFor function could probably live in testUtil as well. At the least, this file should be moved out of the test/spec/util directory and up into the should be test directory, as it's not a test spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I think this was done a long time ago in the original PR, and I was trying to make as few changes from that as possible. E.g. there was nothing else in the util directory then, just mwsTool.js!
Knowing me, I also wanted the tests to be low-dependency, and it seemed like there as a lot going on in testUtils...
Anyway, I'm happy to move the code out and into testUtils (I had moved the non-spec files out myself during testing so I could isolate tests w/o the util specs.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, have the changes locally, will update the PR a bit later this afternoon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the changes are up. There were changes to a dozen or so files to enable this, and I included some commented-out test config features that I've found useful for focusing tests and reducing test output clutter.
The mswUtils was moved into a unit/utils directory to clarify purpose and ease inclusion of test utilities (e.g. don't need to individually add that file, don't need to individually map it for requires). asyncUtils was removed and the non-duplicate function (tryFor) moved into testUtils.

// Theoretically this ensures that the link and url are not needed any more.
// I don't know of documentation for this behavior, but it does seem to work.
// Note that there is nothing really to "download", as the heatmap content is
// already loaded in the browser.
Copy link
Member

Choose a reason for hiding this comment

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

👍

// I don't know of documentation for this behavior, but it does seem to work.
// Note that there is nothing really to "download", as the heatmap content is
// already loaded in the browser.
setTimeout(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Is the setTimeout wrapper bit necessary? Is that something to do with the Blob lifecycle?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just added this to the comment:

I didn't find documentation for this, but I figure that the click is
not handled until the next turn of the wheel in the JS event loop. So the
timeout just lets the event loop handle the click, and timers are executed
after any pending events, so this should ensure that the link being clicked
is not removed until the link 'click' is handled.

@eapearson eapearson mentioned this pull request Oct 24, 2022
10 tasks
@sonarqubecloud
Copy link

SonarCloud Quality Gate failed.    Quality Gate failed

Bug C 1 Bug
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 2 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@briehl briehl self-requested a review October 25, 2022 16:12
@briehl
Copy link
Member

briehl commented Oct 25, 2022

Thanks for the changes. This works for me.

@briehl briehl merged commit 0688db9 into develop Oct 25, 2022
@briehl briehl deleted the PTV-1620-browser-freeze branch October 25, 2022 16:13
briehl added a commit that referenced this pull request Oct 26, 2022
@eapearson
Copy link
Contributor Author

Just adding a comment to note that this implements a sub ticket of PTV-1620: PTV-1844

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.

2 participants