* Fix #2473 - Use sidekiq scheduler to refresh PuSH subscriptions instead of cron Fix an issue where / in domain would raise exception in TagManager#normalize_domain PuSH subscriptions refresh done in a round-robin way to avoid hammering a single server's hub in sequence. Correct handling of failures/retries through Sidekiq (see also #2613). Optimize Account#with_followers scope. Also, since subscriptions are now delegated to Sidekiq jobs, an uncaught exception will not stop the entire refreshing operation halfway through Fix #2702 - Correct user agent header on outgoing http requests * Add test for SubscribeService * Extract #expiring_accounts into method * Make mastodon:push:refresh no-op * Queues are now defined in sidekiq.yml * Queues are now in sidekiq.yml
		
			
				
	
	
		
			36 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			36 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
class SubscribeService < BaseService
 | 
						|
  def call(account)
 | 
						|
    account.secret = SecureRandom.hex
 | 
						|
 | 
						|
    subscription = account.subscription(api_subscription_url(account.id))
 | 
						|
    response     = subscription.subscribe
 | 
						|
 | 
						|
    if response_failed_permanently?(response)
 | 
						|
      # An error in the 4xx range (except for 429, which is rate limiting)
 | 
						|
      # means we're not allowed to subscribe. Fail and move on
 | 
						|
      account.secret = ''
 | 
						|
      account.save!
 | 
						|
    elsif response_successful?(response)
 | 
						|
      # Anything in the 2xx range means the subscription will be confirmed
 | 
						|
      # asynchronously, we've done what we needed to do
 | 
						|
      account.save!
 | 
						|
    else
 | 
						|
      # What's left is the 5xx range and 429, which means we need to retry
 | 
						|
      # at a later time. Fail loudly!
 | 
						|
      raise "Subscription attempt failed for #{account.acct} (#{account.hub_url}): HTTP #{response.code}"
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  private
 | 
						|
 | 
						|
  def response_failed_permanently?(response)
 | 
						|
    response.code > 299 && response.code < 500 && response.code != 429
 | 
						|
  end
 | 
						|
 | 
						|
  def response_successful?(response)
 | 
						|
    response.code > 199 && response.code < 300
 | 
						|
  end
 | 
						|
end
 |