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
Changing an organization's image should invalidate the associated articles cached organization #17041
Comments
Thanks for the issue, we will take it into consideration! Our team of engineers is busy working on many types of features, please give us time to get back to you. Feature requests that require more discussion may be closed. Read more about our feature request process on forem.dev. To our amazing contributors: issues labeled To claim an issue to work on, please leave a comment. If you've claimed the issue and need help, please ping @forem/oss. The OSS Community Manager or the engineers on OSS rotation will follow up. For full info on how to contribute, please check out our contributors guide. |
In helping track down #17041 I was looking at our cache busting logic. We were looking up a constant via the `.const_get` call from a string already defined inline. This refactor short-circuits naming a string, capitalizing it, then looking in the class's registered constants. There's also a subtle bug in the original; When `provider` equals "another_cache", the `#capitalize` method would return `"Another_cache"`, whereas `#classify` will return `"AnotherCache"`. Below are some benchmarks for the change. ```ruby require "benchmark" module EdgeCache class Bust def by_class Fastly end def by_const_get self.class.const_get("fastly".classify) end end end Benchmark.bmbm do |x| x.report("by_class") do 1000.times do EdgeCache::Bust.new.by_class end end x.report("by_const_get") do 1000.times do EdgeCache::Bust.new.by_const_get end end end ``` ```shell > bin/rails runner /Users/jfriesen/git/forem/bench.rb Rehearsal ------------------------------------------------ by_class 0.001239 0.000186 0.001425 ( 0.001342) by_const_get 0.011398 0.000136 0.011534 ( 0.011538) --------------------------------------- total: 0.012959sec user system total real by_class 0.000973 0.000030 0.001003 ( 0.000969) by_const_get 0.011102 0.000032 0.011134 ( 0.011104) ```
In helping track down #17041 I was looking at our cache busting logic. We were looking up a constant via the `.const_get` call from a string already defined inline. This refactor short-circuits naming a string, capitalizing it, then looking in the class's registered constants. There's also a subtle bug in the original; When `provider` equals "another_cache", the `#capitalize` method would return `"Another_cache"`, whereas `#classify` will return `"AnotherCache"`. Below are some benchmarks for the change. ```ruby require "benchmark" module EdgeCache class Bust def by_class Fastly end def by_const_get self.class.const_get("fastly".classify) end end end Benchmark.bmbm do |x| x.report("by_class") do 1000.times do EdgeCache::Bust.new.by_class end end x.report("by_const_get") do 1000.times do EdgeCache::Bust.new.by_const_get end end end ``` ```shell > bin/rails runner /Users/jfriesen/git/forem/bench.rb Rehearsal ------------------------------------------------ by_class 0.001239 0.000186 0.001425 ( 0.001342) by_const_get 0.011398 0.000136 0.011534 ( 0.011538) --------------------------------------- total: 0.012959sec user system total real by_class 0.000973 0.000030 0.001003 ( 0.000969) by_const_get 0.011102 0.000032 0.011134 ( 0.011104) ```
Prior to this commit, when we change attributes for a user we might resave each article. The purpose of the resave was to handle some of the cached attributes of an article. We need to extend this behavior into organizations. When an organization changes it's icon, we want to update each article associated with the organization. While this change doesn't do that, it does make it easier for this update to happen. This begins to address #17041
Prior to this commit, when we change attributes for a user we might resave each article. The purpose of the resave is to update some of the cached attributes of an article. We need to extend this behavior into organizations. When an organization changes it's icon, we want to update each article associated with the organization. While this change doesn't do that, it does make it easier for this update to happen. This also removes some redundant code. The following removed code has an `article.save` call. Which, the callbacks in the article (see below) already clear the cache. ```ruby def resave_articles articles.find_each do |article| if article.path cache_bust = EdgeCache::Bust.new cache_bust.call(article.path) cache_bust.call("#{article.path}?i=i") end article.save end end ``` https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L164 https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L881-L888 This begins to address #17041
In the Organization model we have the following: forem/app/models/organization.rb Lines 144 to 154 in 0fc1a40
Which are called in these two spots: forem/app/models/organization.rb Line 18 in 0fc1a40
forem/app/models/organization.rb Line 26 in 0fc1a40
And as part of "updating" the articles, we call the following: Line 152 in 0fc1a40
Which has the method body: Lines 828 to 831 in 0fc1a40
So we're attempting to update an article's cached organization three different times. And it is possible that the We definitely don't need to update these things so many times. |
There are three major things occurring in this pull request: 1. Renaming `Article#update_cached_user` to `Article#set_cached_entities`. 2. Reducing an organization's direct knowledge of which of the org's attributes an article caches. 3. Removing duplicate calls to update the article associated with the organization. For renaming to `Article#set_cached_entities`, the prior method implied we were updating the persistence layer. However, we were not making any save nor update calls. This rename should clarify intention. For reducing knowledge, the comments for `Article::ATTRIBUTES_CACHED_FOR_RELATED_ENTITY` should explain the details. And last, removing the duplicate calls; we had three methods that were attempting to build and update the `Article#cached_organization`'s value. Closes #17041
Informed by forem/forem#17052 and forem/forem#17041
There are three major things occurring in this pull request: 1. Renaming `Article#update_cached_user` to `Article#set_cached_entities`. 2. Reducing an organization's direct knowledge of which of the org's attributes an article caches. 3. Removing duplicate calls to update the article associated with the organization. For renaming to `Article#set_cached_entities`, the prior method implied we were updating the persistence layer. However, we were not making any save nor update calls. This rename should clarify intention. For reducing knowledge, the comments for `Article::ATTRIBUTES_CACHED_FOR_RELATED_ENTITY` should explain the details. And last, removing the duplicate calls; we had three methods that were attempting to build and update the `Article#cached_organization`'s value. Closes #17041
Prior to this commit, when we change attributes for a user we might resave each article. The purpose of the resave is to update some of the cached attributes of an article. This removes some redundant code. The following removed code has an `article.save` call. Which, the callbacks in the article (see below) already clear the cache. ```ruby def resave_articles articles.find_each do |article| if article.path cache_bust = EdgeCache::Bust.new cache_bust.call(article.path) cache_bust.call("#{article.path}?i=i") end article.save end end ``` https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L164 https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L881-L888 This was discovered in triaging #17041
Prior to this commit, when we change attributes for a user we might resave each article. The purpose of the resave is to update some of the cached attributes of an article. This removes some redundant code. The following removed code has an `article.save` call. Which, the callbacks in the article (see below) already clear the cache. ```ruby def resave_articles articles.find_each do |article| if article.path cache_bust = EdgeCache::Bust.new cache_bust.call(article.path) cache_bust.call("#{article.path}?i=i") end article.save end end ``` https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L164 https://github.com/forem/forem/blob/8e6981aac59e86a9a2c69db1e50fb1119f509c8d/app/models/article.rb#L881-L888 This was discovered in triaging #17041
Current behavior:
Expected behavior:
In the below image, I would expect that if I changed the DEV image to something else that the DEV icon behind Gracie would reflect that change.
The following code highlights how we cache the article's organization:
forem/app/views/articles/_single_story.html.erb
Lines 26 to 30 in f5ae290
The current work around is that you would need to edit all articles to recalculate the cache.
The text was updated successfully, but these errors were encountered: