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

teal reactivity solution 2 #806

Merged
merged 15 commits into from
Feb 23, 2023
Merged

teal reactivity solution 2 #806

merged 15 commits into from
Feb 23, 2023

Conversation

mhallal1
Copy link
Collaborator

closes #803

Solution 2 to solve the reactivity of teal apps:

  1. Transformed srv_nested_tabs.teal_module into moduleServer
  2. Added a NULL renderUI in srv_nested_tabs.teal_module to trigger the filtered data when the tab is changed
  3. Updated .datasets_to_data to accept a reactiveVal trigger function to refresh the filtered data
  4. Updated and added a couple of tests

Please test with exploratory app or similar apps.

@mhallal1 mhallal1 added the core label Feb 13, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2023

badge

Code Coverage Summary

Filename                         Stmts    Miss  Cover    Missing
-----------------------------  -------  ------  -------  ------------------------------
R/dummy_functions.R                 74      61  17.57%   12-95
R/example_module.R                  18       9  50.00%   23-26, 29-33
R/get_rcode_utils.R                 52       2  96.15%   94, 99
R/get_rcode.R                      137      54  60.58%   74, 81, 86, 211-277
R/include_css_js.R                  24       0  100.00%
R/init.R                            22       2  90.91%   188-189
R/module_nested_tabs.R             161       7  95.65%   57, 97, 101-102, 137, 188, 240
R/module_tabs_with_filters.R        68       1  98.53%   162
R/module_teal_with_splash.R         33       2  93.94%   65, 77
R/module_teal.R                    111       5  95.50%   49, 52, 155-156, 180
R/modules_debugging.R               18      18  0.00%    37-56
R/modules.R                        101       8  92.08%   341-366
R/reporter_previewer_module.R       12       2  83.33%   18, 22
R/show_rcode_modal.R                20      20  0.00%    17-38
R/tdata.R                           41       2  95.12%   146, 172
R/utils.R                           13       0  100.00%
R/validate_inputs.R                 32       0  100.00%
R/validations.R                     62      39  37.10%   107-368
R/zzz.R                             11       7  36.36%   3-14
TOTAL                             1010     239  76.34%

Diff against main

Filename                  Stmts    Miss  Cover
----------------------  -------  ------  -------
R/module_nested_tabs.R      +31       0  +1.04%
TOTAL                       +31       0  +0.75%

Results for commit: 04a81ad

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

@mhallal1 mhallal1 requested a review from gogonzo February 13, 2023 14:29
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2023

Unit Tests Summary

    1 files    13 suites   12s ⏱️
154 tests 154 ✔️ 0 💤 0
301 runs  301 ✔️ 0 💤 0

Results for commit 2476862.

♻️ This comment has been updated with latest results.

@donyunardi
Copy link
Contributor

Looking at the log, it looks like module will only be processed when clicked.
However, adding filter(s) felt significantly slower than usual.
There are lots of trace generated during filtering activity.

Can you try it on your end?

@github-actions
Copy link
Contributor

github-actions bot commented Feb 14, 2023

Unit Test Performance Difference

Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_nested_tabs 👶 $+0.10$ .datasets_to_data_accepts_a_reactiveVal_as_trigger_data_input
module_nested_tabs 👶 $+0.03$ .datasets_to_data_throws_error_if_trigger_data_is_not_a_reactiveVal_function
module_nested_tabs 💀 $0.02$ $-0.02$ nested_teal_modules_are_initialized
module_nested_tabs 👶 $+0.14$ nested_teal_modules_are_initialized_when_the_UI_is_triggered
module_nested_tabs 💀 $0.07$ $-0.07$ passed_shiny_module_is_initialized
module_nested_tabs 👶 $+0.12$ passed_shiny_module_is_initialized_only_when_the_UI_is_triggered
module_nested_tabs 👶 $+0.03$ srv_nested_tabs.teal_module_does_not_pass_data_if_not_in_the_args_explicitly
module_nested_tabs 👶 $+0.08$ srv_nested_tabs.teal_module_does_pass_data_if_in_the_args_explicitly
module_nested_tabs 💀 $0.03$ $-0.03$ srv_nested_tabs.teal_module_doesn_t_pass_data_if_not_in_the_args_explicitly
module_nested_tabs 👶 $+0.02$ srv_nested_tabs.teal_module_passes_filter_panel_api_when_passed_in_the_args_explicitly

Results for commit 04a81ad

♻️ This comment has been updated with latest results.

@mhallal1
Copy link
Collaborator Author

Looking at the log, it looks like module will only be processed when clicked. However, adding filter(s) felt significantly slower than usual. There are lots of trace generated during filtering activity.

Can you try it on your end?

Could you be more specific with an example or a screenshot of the logs to compare?
I did not notice this behaviour.

@donyunardi
Copy link
Contributor

I tried it again and I don't see the behavior anymore, maybe my machine was too cluttered last night.
I tried with multiple example apps and it feels good.
Thanks for working on this!

Just for sanity check can someone else also test this out?

Comment on lines +205 to +207
lapply(datanames, function(x) {
datasets$get_data(x, filtered = TRUE)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

I will measure timing of this and in the line 268: eventReactive(trigger_data(), datasets$get_data(x, filtered = TRUE))

I hope double evaluation of get_data() doesn't influence anything (filter operation suppose to be cached)

Copy link
Contributor

Choose a reason for hiding this comment

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

I confirm that reactive in FilteredDataset$dataset_filtered is evaluated once and cached. This means that each datasets$get_data() takes just fractions of the seconds. So having multiple datasets$get_data() here doesn't have any influence on the performance.

Copy link
Contributor

@gogonzo gogonzo left a comment

Choose a reason for hiding this comment

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

I prefer this solution over #804 as it doesn't need any additional changes. Also module_nested_tabs are less complicated as they don't need passing module_id to determine what is active. Apps works as expected. I give a pre-approval

checkmate::assert_class(datasets, "FilteredData")
args <- isolate(teal.transform::resolve_delayed(modules$ui_args, datasets))
args <- c(list(id = id), args)
args <- c(list(id = ns("module")), args)
Copy link
Contributor

Choose a reason for hiding this comment

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

line 102 - just checking that that's ok (for example missing_data and variable_browser have data in the UI)

Copy link
Contributor

@nikolas-burkoff nikolas-burkoff left a comment

Choose a reason for hiding this comment

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

Code looks good, I'd definitely recommend using this PR over the other one which can be closed. Will run some tests and then approve

@nikolas-burkoff
Copy link
Contributor

It would be great if this doesn't trigger on initialization of the app only when the tab is created

@@ -223,7 +285,7 @@ testthat::test_that("srv_nested_tabs.teal_module doesn't pass filter_panel_api i
moduleServer(id, function(input, output, session) checkmate::assert_class(filter_panel_api, "FilterPanelAPI"))
})

testthat::expect_error(
testthat::expect_warning(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I could not find a better way to improve this test. It passes but throws an error internally.
The test does not really test what it claims it is testing.

Copy link
Contributor

@nikolas-burkoff nikolas-burkoff Feb 23, 2023

Choose a reason for hiding this comment

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

So I wonder if using rlang::env_has(environment(), "data", inherit = FALSE) (or datasets, or filterpanelapi) would help here? Or something similar?

Copy link
Contributor

Choose a reason for hiding this comment

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

for the not passed case we want this:

moduleServer(id, function(input, output, session) {
      checkmate::assert_false(
        tryCatch(
          checkmate::test_class(data, "tdata"),
          error = function(cond) FALSE
        )
      )
    })
 ```
and you replace data with datasets/filter_panel_api

for the it is passed case we can have assert_class() directly
and then expect_no_error (or expect_error(..., NA)) for the testserver

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done.

Copy link
Contributor

@nikolas-burkoff nikolas-burkoff left a comment

Choose a reason for hiding this comment

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

Once my comment inline is addressed (and if using expect_no_error then the version of testthat needs to be bumped up in the DESC file) this can be merged in

@mhallal1 mhallal1 merged commit 236eae2 into main Feb 23, 2023
@mhallal1 mhallal1 deleted the 803_reactivity_v2@main branch February 23, 2023 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG]: teal apps are slow and vulnerable to the change in the data
5 participants