8000 Support async_count for scopes by jdlubrano · Pull Request #8394 · activeadmin/activeadmin · GitHub
[go: up one dir, main page]

Skip to content

Support async_count for scopes #8394

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

Merged

Conversation

jdlubrano
Copy link
Contributor
@jdlubrano jdlubrano commented Jul 9, 2024

Background

In ActiveAdmin applications, a surprising performance bottleneck can be the COUNT queries that run to provide counts for each scope made available on an resource's index page. In many cases, performance issues can be addressed by adding missing indices and/or otherwise speeding up the underlying query.

There is another performance boost that could be low-hanging fruit, however. The COUNT queries for scopes currently run sequentially. In Rails 7.1, the framework provides the async_count method that allows queries to be run in parallel. For index pages with many scopes (and many COUNTs) running queries in parallel could offer a significant time savings.

This PR will use async_count to query the collection size of scopes in versions of Rails where async_count is available. Rails apps not running on Rails 7.1 will continue to rely on sequential queries.

Approach

This PR introduces an ActiveAdmin::AsyncCount class that quacks enough like an ActiveRecord Relation to play nicely with the collection_size helper. The ActiveAdmin::Views::Scopes class eagerly initializes AsyncCounts for each scope that is configured like

scope(:my_scope, show_count: :async)

which kicks off async queries. As a result, rendering the scopes component should only be as slow as its slowest COUNT.

Closed Questions

  • Should the async query behavior be more opt-in? ✅ (it was made more opt-in in the latest commits)
    • Should individual scopes have an async_count: true option? (I choose show_count: :async to leverage the existing show_count attribute)
    • Should the index options support a scope_count: :async option? (It seems easy enough to configure many scopes to use async_count using the with_options Rails/ActiveSupport helper. Example:
with_options(show_count: :async) do
  scope(:one)
  scope(:two)
end
  • Should consumers be able to configure their own ScopeCounter class globally and/or per index? Not necessary

Credits

@tuffylock @aturar

@jdlubrano jdlubrano marked this pull request as ready for review July 10, 2024 03:09
Copy link
codecov bot commented Jul 11, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.11%. Comparing base (6165e14) to head (415ffb0).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #8394   +/-   ##
=======================================
  Coverage   99.10%   99.11%           
=======================================
  Files         140      141    +1     
  Lines        4029     4055   +26     
=======================================
+ Hits         3993     4019   +26     
  Misses         36       36           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jdlubrano
Copy link
Contributor Author

Hi @javierjulio. I was wondering if there was any interest in this PR from the ActiveAdmin maintainers. If not, I have no issue closing it. Sorry about the direct ping, I was looking for a maintainer to nudge.

@javierjulio
Copy link
Member

@jdlubrano thank you. Just have to be patient for us to find time.

I agree this can be a helpful feature. I haven't tried the new async querying capability in Rails yet so I'll have to rely on others for input. Looking at the scopes DSL in our docs, it seems best that this would be an option per scope and that it should be an opt-in feature.

I'm not sure about your last question though. What need do you see for having the ability to override the class?

@jdlubrano
Copy link
Contributor Author

Thanks so much for the feedback!

I will work on tweaking this to rely on a per-scope, opt-in action. Given the per-scope option, I don't see a need to leave the class open to overrides.

@jdlubrano jdlubrano force-pushed the perf/async_counts-for-scopes-4 branch 2 times, most recently from c974cd1 to 7f0ab34 Compare July 26, 2024 21:39
@jdlubrano
Copy link
Contributor Author

I have updated scopes to accept an option like

scope(:my_scope, show_count: :async)

as a way to opt-in to async queries. If someone uses show_count: :async with a version of Rails/ActiveRecord that does not implement async_count, a NoMethodError will be raised. Since this behavior is opt-in, that seems okay to me.

The PR description has also been updated accordingly.

@jdlubrano jdlubrano force-pushed the perf/async_counts-for-scopes-4 branch from 7f0ab34 to 58c1c00 Compare July 26, 2024 23:32
Copy link
Contributor
@mgrunberg mgrunberg left a comment

Choose a reason for hiding this comment

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

@jdlubrano thanks for your work. I like the PR feature.
I wrote a few comments. I want to know your thoughts about them.

I hope I have more time tomorrow to keep reviewing the PR.

@jdlubrano jdlubrano force-pushed the perf/async_counts-for-scopes-4 branch from 71e7125 to f4205c3 Compare August 12, 2024 14:29
javierjulio force-pushed the perf/async_counts-for-scopes-4 branch from f4205c3 to 32dfecf Compare August 14, 2024 21:46
Copy link
Member
@javierjulio javierjulio left a comment

Choose a reason for hiding this comment

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

@mgrunberg I think this is ready and looks good to me. Would you be able to test it out?

Copy link
Contributor
@mgrunberg mgrunberg left a comment

Choose a reason for hiding this comment

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

@javierjulio looks good to me.

I tested it on my machine and it works. I have a simple suggestion before merging.

@javierjulio javierjulio force-pushed the perf/async_counts-for-scopes-4 branch from 8b044d9 to 415ffb0 Compare August 19, 2024 23:39
Copy link
Member
@javierjulio javierjulio left a comment

Choose a reason for hiding this comment

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

Thanks!

@javierjulio javierjulio merged commit 06cac27 into activeadmin:master Aug 19, 2024
24 checks passed
@jdlubrano jdlubrano deleted the perf/async_counts-for-scopes-4 branch August 20, 2024 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0