mirror of
https://github.com/discourse/discourse.git
synced 2026-08-03 09:53:24 -05:00
PERF: optimize GitHub PR onebox rebaking (#36739)
Previously, when rebaking posts containing GitHub PR oneboxes, we passed `invalidate_oneboxes: true` to `rebake!` which would re-fetch the onebox during cooking. This meant each post independently fetched the same PR data from GitHub. Now we: 1. Fetch and cache the onebox once upfront via `Oneboxer.preview` 2. Use the new `skip_publish_rebaked_changes` parameter to prevent publishing intermediate states, without triggering onebox re-fetches 3. Filter posts by `cooked LIKE '%githubpullrequest%'` in SQL rather than fetching all linked posts and filtering in Ruby The new `skip_publish_rebaked_changes` parameter on `Post#rebake!` allows callers to skip the `:rebaked` publish without triggering onebox invalidation, which is useful when the caller has already refreshed the cache separately.
This commit is contained in:
@@ -5,48 +5,38 @@ module Jobs
|
||||
sidekiq_options queue: "low"
|
||||
|
||||
def execute(args)
|
||||
pr_url = args[:pr_url]
|
||||
return if pr_url.blank?
|
||||
url = args[:pr_url]
|
||||
return if url.blank?
|
||||
|
||||
rebake_posts(pr_url)
|
||||
rebake_chat_messages(pr_url) if SiteSetting.chat_enabled
|
||||
# invalidate & refresh the onebox cache for this PR URL
|
||||
Oneboxer.preview(url, invalidate_oneboxes: true)
|
||||
|
||||
rebake_posts(url)
|
||||
rebake_chat_messages(url) if SiteSetting.chat_enabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rebake_posts(pr_url)
|
||||
post_ids =
|
||||
TopicLink
|
||||
.where(url: pr_url)
|
||||
.or(TopicLink.where("url LIKE ?", "#{pr_url}%"))
|
||||
.select(:post_id)
|
||||
def rebake_posts(url)
|
||||
post_ids = TopicLink.where(url:).or(TopicLink.where("url LIKE ?", "#{url}%")).select(:post_id)
|
||||
|
||||
Post
|
||||
.where(id: post_ids)
|
||||
.find_each do |post|
|
||||
next unless has_github_pr_onebox?(post.cooked, pr_url)
|
||||
post.rebake!(invalidate_oneboxes: true, priority: :low)
|
||||
end
|
||||
.where("cooked LIKE ?", "%githubpullrequest%#{url}%")
|
||||
.find_each { |post| post.rebake!(priority: :low, skip_publish_rebaked_changes: true) }
|
||||
end
|
||||
|
||||
def rebake_chat_messages(pr_url)
|
||||
def rebake_chat_messages(url)
|
||||
message_ids =
|
||||
::Chat::MessageLink
|
||||
.where(url: pr_url)
|
||||
.or(::Chat::MessageLink.where("url LIKE ?", "#{pr_url}%"))
|
||||
.where(url:)
|
||||
.or(::Chat::MessageLink.where("url LIKE ?", "#{url}%"))
|
||||
.select(:chat_message_id)
|
||||
|
||||
::Chat::Message
|
||||
.where(id: message_ids)
|
||||
.find_each do |message|
|
||||
next unless has_github_pr_onebox?(message.cooked, pr_url)
|
||||
message.rebake!(invalidate_oneboxes: true, priority: :low, skip_notifications: true)
|
||||
end
|
||||
end
|
||||
|
||||
def has_github_pr_onebox?(cooked, pr_url)
|
||||
# quick & dirty check to avoid doing unnecessary rebakes
|
||||
cooked.present? && cooked.include?("githubpullrequest") && cooked.include?(pr_url)
|
||||
.where("cooked LIKE ?", "%githubpullrequest%#{url}%")
|
||||
.find_each { |message| message.rebake!(priority: :low, skip_notifications: true) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user