about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-11-08 21:05:42 +0100
committerGitHub <noreply@github.com>2018-11-08 21:05:42 +0100
commit6d59dfa15d873da75c731b79367ab6b3d1b2f5a5 (patch)
tree4dda07058520c878354b95ab736ec9f6a36f4d03 /app/services
parent9cfd610484541c14bcde3c368a158b9b5d2a6499 (diff)
Optimize the process of following someone (#9220)
* Eliminate extra accounts select query from FollowService

* Optimistically update follow state in web UI and hide loading bar

Fix #6205

* Asynchronize NotifyService in FollowService

And fix failing test

* Skip Webfinger resolve routine when called from FollowService if possible

If an account is ActivityPub, then webfinger re-resolving is not necessary
when called from FollowService. Improve options of ResolveAccountService
Diffstat (limited to 'app/services')
-rw-r--r--app/services/concerns/author_extractor.rb2
-rw-r--r--app/services/follow_service.rb8
-rw-r--r--app/services/process_mentions_service.rb2
-rw-r--r--app/services/resolve_account_service.rb32
4 files changed, 27 insertions, 17 deletions
diff --git a/app/services/concerns/author_extractor.rb b/app/services/concerns/author_extractor.rb
index 1e00eb803..c2419e9ec 100644
--- a/app/services/concerns/author_extractor.rb
+++ b/app/services/concerns/author_extractor.rb
@@ -18,6 +18,6 @@ module AuthorExtractor
       acct   = "#{username}@#{domain}"
     end
 
-    ResolveAccountService.new.call(acct, update_profile)
+    ResolveAccountService.new.call(acct, update_profile: update_profile)
   end
 end
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index f6888a68d..0020bc9fe 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -7,9 +7,9 @@ class FollowService < BaseService
   # @param [Account] source_account From which to follow
   # @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
   # @param [true, false, nil] reblogs Whether or not to show reblogs, defaults to true
-  def call(source_account, uri, reblogs: nil)
+  def call(source_account, target_account, reblogs: nil)
     reblogs = true if reblogs.nil?
-    target_account = uri.is_a?(Account) ? uri : ResolveAccountService.new.call(uri)
+    target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
 
     raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended?
     raise Mastodon::NotPermittedError  if target_account.blocking?(source_account) || source_account.blocking?(target_account)
@@ -42,7 +42,7 @@ class FollowService < BaseService
     follow_request = FollowRequest.create!(account: source_account, target_account: target_account, show_reblogs: reblogs)
 
     if target_account.local?
-      NotifyService.new.call(target_account, follow_request)
+      LocalNotificationWorker.perform_async(target_account.id, follow_request.id, follow_request.class.name)
     elsif target_account.ostatus?
       NotificationWorker.perform_async(build_follow_request_xml(follow_request), source_account.id, target_account.id)
       AfterRemoteFollowRequestWorker.perform_async(follow_request.id)
@@ -57,7 +57,7 @@ class FollowService < BaseService
     follow = source_account.follow!(target_account, reblogs: reblogs)
 
     if target_account.local?
-      NotifyService.new.call(target_account, follow)
+      LocalNotificationWorker.perform_async(target_account.id, follow.id, follow.class.name)
     else
       Pubsubhubbub::SubscribeWorker.perform_async(target_account.id) unless target_account.subscribed?
       NotificationWorker.perform_async(build_follow_xml(follow), source_account.id, target_account.id)
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index b4641c4b4..ec7d33b1d 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -47,7 +47,7 @@ class ProcessMentionsService < BaseService
     mentioned_account = mention.account
 
     if mentioned_account.local?
-      LocalNotificationWorker.perform_async(mention.id)
+      LocalNotificationWorker.perform_async(mentioned_account.id, mention.id, mention.class.name)
     elsif mentioned_account.ostatus? && !@status.stream_entry.hidden?
       NotificationWorker.perform_async(ostatus_xml, @status.account_id, mentioned_account.id)
     elsif mentioned_account.activitypub?
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index 4323e7f06..c3064211d 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -9,17 +9,27 @@ class ResolveAccountService < BaseService
   # Find or create a local account for a remote user.
   # When creating, look up the user's webfinger and fetch all
   # important information from their feed
-  # @param [String] uri User URI in the form of username@domain
+  # @param [String, Account] uri User URI in the form of username@domain
+  # @param [Hash] options
   # @return [Account]
-  def call(uri, update_profile = true, redirected = nil)
-    @username, @domain = uri.split('@')
-    @update_profile    = update_profile
+  def call(uri, options = {})
+    @options = options
 
-    return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
+    if uri.is_a?(Account)
+      @account  = uri
+      @username = @account.username
+      @domain   = @account.domain
+
+      return @account if @account.local? || !webfinger_update_due?
+    else
+      @username, @domain = uri.split('@')
 
-    @account = Account.find_remote(@username, @domain)
+      return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
 
-    return @account unless webfinger_update_due?
+      @account = Account.find_remote(@username, @domain)
+
+      return @account unless webfinger_update_due?
+    end
 
     Rails.logger.debug "Looking up webfinger for #{uri}"
 
@@ -30,8 +40,8 @@ class ResolveAccountService < BaseService
     if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
       @username = confirmed_username
       @domain   = confirmed_domain
-    elsif redirected.nil?
-      return call("#{confirmed_username}@#{confirmed_domain}", update_profile, true)
+    elsif options[:redirected].nil?
+      return call("#{confirmed_username}@#{confirmed_domain}", options.merge(redirected: true))
     else
       Rails.logger.debug 'Requested and returned acct URIs do not match'
       return
@@ -76,7 +86,7 @@ class ResolveAccountService < BaseService
   end
 
   def webfinger_update_due?
-    @account.nil? || @account.possibly_stale?
+    @account.nil? || ((!@options[:skip_webfinger] || @account.ostatus?) && @account.possibly_stale?)
   end
 
   def activitypub_ready?
@@ -93,7 +103,7 @@ class ResolveAccountService < BaseService
   end
 
   def update_profile?
-    @update_profile
+    @options[:update_profile]
   end
 
   def handle_activitypub