commit: 6e9eda53319bc970b085c7c55277981320b2a835
parent: 4c23544714c05258af8feab50da243039ddbefb6
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 21 Aug 2017 01:14:40 +0200
ActivityPub migration procedure (#4617)
* ActivityPub migration procedure
Once one account is detected as going from OStatus to ActivityPub,
invalidate WebFinger cache for other accounts from the same domain
* Unsubscribe from PuSH updates once we receive an ActivityPub payload
* Re-subscribe to PuSH unless already unsubscribed, regardless of protocol
Diffstat:
8 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
@@ -7,6 +7,7 @@ class ActivityPub::InboxesController < Api::BaseController
def create
if signed_request_account
+ upgrade_account
process_payload
head 201
else
@@ -24,6 +25,11 @@ class ActivityPub::InboxesController < Api::BaseController
@body ||= request.body.read
end
+ def upgrade_account
+ return unless signed_request_account.subscribed?
+ Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id)
+ end
+
def process_payload
ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'))
end
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
@@ -17,7 +17,7 @@ module Admin
end
def unsubscribe
- UnsubscribeService.new.call(@account)
+ Pubsubhubbub::UnsubscribeWorker.perform_async(@account.id)
redirect_to admin_account_path(@account.id)
end
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
@@ -12,7 +12,8 @@ class ActivityPub::ProcessAccountService < BaseService
@domain = domain
@account = Account.find_by(uri: @uri)
- create_account if @account.nil?
+ create_account if @account.nil?
+ upgrade_account if @account.ostatus?
update_account
@account
@@ -24,6 +25,7 @@ class ActivityPub::ProcessAccountService < BaseService
def create_account
@account = Account.new
+ @account.protocol = :activitypub
@account.username = @username
@account.domain = @domain
@account.uri = @uri
@@ -50,6 +52,10 @@ class ActivityPub::ProcessAccountService < BaseService
@account.save!
end
+ def upgrade_account
+ ActivityPub::PostUpgradeWorker.perform_async(@account.domain)
+ end
+
def image_url(key)
value = first_of_value(@json[key])
diff --git a/app/services/unsubscribe_service.rb b/app/services/unsubscribe_service.rb
@@ -2,7 +2,7 @@
class UnsubscribeService < BaseService
def call(account)
- return unless account.ostatus?
+ return if account.hub_url.blank?
@account = account
@response = build_request.perform
diff --git a/app/workers/activitypub/post_upgrade_worker.rb b/app/workers/activitypub/post_upgrade_worker.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ActivityPub::PostUpgradeWorker
+ include Sidekiq::Worker
+
+ sidekiq_options queue: 'pull'
+
+ def perform(domain)
+ Account.where(domain: domain)
+ .where(protocol: :ostatus)
+ .where.not(last_webfingered_at: nil)
+ .in_batches
+ .update_all(last_webfingered_at: nil)
+ end
+end
diff --git a/app/workers/pubsubhubbub/unsubscribe_worker.rb b/app/workers/pubsubhubbub/unsubscribe_worker.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class Pubsubhubbub::UnsubscribeWorker
+ include Sidekiq::Worker
+
+ sidekiq_options queue: 'push', retry: false, unique: :until_executed, dead: false
+
+ def perform(account_id)
+ account = Account.find(account_id)
+ logger.debug "PuSH unsubscribing from #{account.acct}"
+ ::UnsubscribeService.new.call(account)
+ rescue ActiveRecord::RecordNotFound
+ true
+ end
+end
diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb
@@ -14,6 +14,6 @@ class Scheduler::SubscriptionsScheduler
private
def expiring_accounts
- Account.where(protocol: :ostatus).expiring(1.day.from_now).partitioned
+ Account.expiring(1.day.from_now).partitioned
end
end
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
@@ -111,10 +111,7 @@ namespace :mastodon do
namespace :push do
desc 'Unsubscribes from PuSH updates of feeds nobody follows locally'
task clear: :environment do
- Account.remote.without_followers.where.not(subscription_expires_at: nil).find_each do |a|
- Rails.logger.debug "PuSH unsubscribing from #{a.acct}"
- UnsubscribeService.new.call(a)
- end
+ Pubsubhubbub::UnsubscribeWorker.push_bulk(Account.remote.without_followers.where.not(subscription_expires_at: nil).pluck(:id))
end
desc 'Re-subscribes to soon expiring PuSH subscriptions (deprecated)'