diff --git a/app/workers/activitypub/fetch_all_replies_worker.rb b/app/workers/activitypub/fetch_all_replies_worker.rb index 0f4fd83caf6a78..c9863647c9de91 100644 --- a/app/workers/activitypub/fetch_all_replies_worker.rb +++ b/app/workers/activitypub/fetch_all_replies_worker.rb @@ -18,7 +18,12 @@ def perform(parent_status_id, options = {}) @parent_status = Status.find(parent_status_id) Rails.logger.debug { "FetchAllRepliesWorker - #{@parent_status.uri}: Fetching all replies for status: #{@parent_status}" } - uris_to_fetch = get_replies(@parent_status.uri, options) + # Refetch parent status and replies with one request + @parent_status_json = fetch_resource(@parent_status.uri, true) + raise UnexpectedResponseError("Could not fetch ActivityPub JSON for parent status: #{@parent_status.uri}") if @parent_status_json.nil? + + FetchReplyWorker.perform_async(@parent_status.uri, { 'prefetched_body' => @parent_status_json }) + uris_to_fetch = get_replies(@parent_status.uri, @parent_status_json, options) return if uris_to_fetch.nil? @parent_status.touch(:fetched_replies_at) @@ -29,7 +34,7 @@ def perform(parent_status_id, options = {}) next_reply = uris_to_fetch.pop next if next_reply.nil? - new_reply_uris = get_replies(next_reply, options) + new_reply_uris = get_replies(next_reply, nil, options) next if new_reply_uris.nil? new_reply_uris = new_reply_uris.reject { |uri| fetched_uris.include?(uri) } @@ -44,16 +49,17 @@ def perform(parent_status_id, options = {}) private - def get_replies(status_uri, options = {}) - replies_collection_or_uri = get_replies_uri(status_uri) + def get_replies(status_uri, prefetched_body = nil, options = {}) + replies_collection_or_uri = get_replies_uri(status_uri, prefetched_body) return if replies_collection_or_uri.nil? ActivityPub::FetchAllRepliesService.new.call(replies_collection_or_uri, **options.deep_symbolize_keys) end - def get_replies_uri(parent_status_uri) + def get_replies_uri(parent_status_uri, prefetched_body = nil) begin - json_status = fetch_resource(parent_status_uri, true) + json_status = prefetched_body.nil? ? fetch_resource(parent_status_uri, true) : prefetched_body + if json_status.nil? Rails.logger.debug { "FetchAllRepliesWorker - #{@parent_status.uri}: error getting replies URI for #{parent_status_uri}, returned nil" } nil diff --git a/app/workers/fetch_reply_worker.rb b/app/workers/fetch_reply_worker.rb index 68a7414bebeaa0..ecb232bbbb0eed 100644 --- a/app/workers/fetch_reply_worker.rb +++ b/app/workers/fetch_reply_worker.rb @@ -7,6 +7,6 @@ class FetchReplyWorker sidekiq_options queue: 'pull', retry: 3 def perform(child_url, options = {}) - FetchRemoteStatusService.new.call(child_url, **options.deep_symbolize_keys) + FetchRemoteStatusService.new.call(child_url, **options.symbolize_keys) end end diff --git a/spec/workers/activitypub/fetch_all_replies_worker_spec.rb b/spec/workers/activitypub/fetch_all_replies_worker_spec.rb index 35fadb6caf1497..bb85cf486367c6 100644 --- a/spec/workers/activitypub/fetch_all_replies_worker_spec.rb +++ b/spec/workers/activitypub/fetch_all_replies_worker_spec.rb @@ -140,6 +140,13 @@ got_uris = subject.perform(status.id) expect(got_uris).to match_array(top_items + top_items_paged) end + + it 'fetches the top status using a prefetched body' do + allow(FetchReplyWorker).to receive(:perform_async) + subject.perform(status.id) + expect(a_request(:get, top_note_uri)).to have_been_made.times(1) + expect(FetchReplyWorker).to have_received(:perform_async).with(top_note_uri, { 'prefetched_body' => top_object.deep_stringify_keys }) + end end describe 'perform' do