about summary refs log tree commit diff
path: root/app/lib
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2020-04-15 20:33:24 +0200
committerGitHub <noreply@github.com>2020-04-15 20:33:24 +0200
commit5edff32733eff2cbffbf614b31eea85da8dc3aaf (patch)
treeb0ab38cbf8793f47017e2151de5dd32bdd83a29a /app/lib
parent5524258da9bc1d62b1396d19c672d3a8335ffbc5 (diff)
Change delivery failure tracking to work with hostnames instead of URLs (#13437)
Diffstat (limited to 'app/lib')
-rw-r--r--app/lib/delivery_failure_tracker.rb34
1 files changed, 20 insertions, 14 deletions
diff --git a/app/lib/delivery_failure_tracker.rb b/app/lib/delivery_failure_tracker.rb
index 8d3be35de..25fa694d2 100644
--- a/app/lib/delivery_failure_tracker.rb
+++ b/app/lib/delivery_failure_tracker.rb
@@ -3,47 +3,53 @@
 class DeliveryFailureTracker
   FAILURE_DAYS_THRESHOLD = 7
 
-  def initialize(inbox_url)
-    @inbox_url = inbox_url
+  def initialize(url_or_host)
+    @host = url_or_host.start_with?('https://') || url_or_host.start_with?('http://') ? Addressable::URI.parse(url_or_host).normalized_host : url_or_host
   end
 
   def track_failure!
     Redis.current.sadd(exhausted_deliveries_key, today)
-    Redis.current.sadd('unavailable_inboxes', @inbox_url) if reached_failure_threshold?
+    UnavailableDomain.create(domain: @host) if reached_failure_threshold?
   end
 
   def track_success!
     Redis.current.del(exhausted_deliveries_key)
-    Redis.current.srem('unavailable_inboxes', @inbox_url)
+    UnavailableDomain.find_by(domain: @host)&.destroy
   end
 
   def days
     Redis.current.scard(exhausted_deliveries_key) || 0
   end
 
+  def available?
+    !UnavailableDomain.where(domain: @host).exists?
+  end
+
+  alias reset! track_success!
+
   class << self
-    def filter(arr)
-      arr.reject(&method(:unavailable?))
-    end
+    def without_unavailable(urls)
+      unavailable_domains_map = Rails.cache.fetch('unavailable_domains') { UnavailableDomain.pluck(:domain).each_with_object({}) { |domain, hash| hash[domain] = true } }
 
-    def unavailable?(url)
-      Redis.current.sismember('unavailable_inboxes', url)
+      urls.reject do |url|
+        host = Addressable::URI.parse(url).normalized_host
+        unavailable_domains_map[host]
+      end
     end
 
     def available?(url)
-      !unavailable?(url)
+      new(url).available?
     end
 
-    def track_inverse_success!(from_account)
-      new(from_account.inbox_url).track_success! if from_account.inbox_url.present?
-      new(from_account.shared_inbox_url).track_success! if from_account.shared_inbox_url.present?
+    def reset!(url)
+      new(url).reset!
     end
   end
 
   private
 
   def exhausted_deliveries_key
-    "exhausted_deliveries:#{@inbox_url}"
+    "exhausted_deliveries:#{@host}"
   end
 
   def today