Compare commits

...

7 Commits

Author SHA1 Message Date
Matt Jankowski
40493cf1df
Merge 84fb6869e2 into 07912a1cb7 2025-07-15 16:06:00 +00:00
Matt Jankowski
84fb6869e2 Update stoplight to version 5.2.0 2025-07-15 09:03:08 -04:00
Matt Jankowski
07370ab5cf Update stoplight to version 5.1.0 2025-07-15 09:02:57 -04:00
Matt Jankowski
7436398308 Use new call style 2025-07-15 09:02:57 -04:00
Matt Jankowski
05626a0ded Use new error handling style 2025-07-15 09:02:57 -04:00
Matt Jankowski
20e7d98192 Upgrade global config style 2025-07-15 09:02:57 -04:00
Matt Jankowski
abdd738c1a Update stoplight to version 5.0.2 2025-07-15 09:02:57 -04:00
7 changed files with 44 additions and 29 deletions

View File

@ -88,7 +88,7 @@ gem 'sidekiq-scheduler', '~> 5.0'
gem 'sidekiq-unique-jobs', '> 8'
gem 'simple_form', '~> 5.2'
gem 'simple-navigation', '~> 4.4'
gem 'stoplight', '~> 4.1'
gem 'stoplight'
gem 'strong_migrations'
gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0'

View File

@ -715,8 +715,6 @@ GEM
redis (4.8.1)
redis-client (0.24.0)
connection_pool
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.10.0)
reline (0.6.1)
io-console (~> 0.5)
@ -852,8 +850,8 @@ GEM
stackprof (0.2.27)
starry (0.2.0)
base64
stoplight (4.1.1)
redlock (~> 1.0)
stoplight (5.2.0)
zeitwerk
stringio (3.1.7)
strong_migrations (2.4.0)
activerecord (>= 7.1)
@ -1085,7 +1083,7 @@ DEPENDENCIES
simplecov (~> 0.22)
simplecov-lcov (~> 0.8)
stackprof
stoplight (~> 4.1)
stoplight
strong_migrations
test-prof
thor (~> 1.2)

View File

@ -9,6 +9,8 @@ module SignatureVerification
EXPIRATION_WINDOW_LIMIT = 12.hours
CLOCK_SKEW_MARGIN = 1.hour
STOPLIGHT_COOL_OFF_TIME = 5.minutes.seconds
STOPLIGHT_THRESHOLD = 1
def require_account_signature!
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
@ -107,10 +109,12 @@ module SignatureVerification
end
def stoplight_wrapper
Stoplight("source:#{request.remote_ip}")
.with_threshold(1)
.with_cool_off_time(5.minutes.seconds)
.with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) }
Stoplight(
"source:#{request.remote_ip}",
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_THRESHOLD,
tracked_errors: [HTTP::Error, OpenSSL::SSL::SSLError]
)
end
def actor_refresh_key!(actor)

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true
class BulkImportRowService
STOPLIGHT_COOL_OFF_TIME = 5.minutes.seconds
STOPLIGHT_THRESHOLD = 1
def call(row)
@account = row.bulk_import.account
@data = row.data
@ -10,7 +13,7 @@ class BulkImportRowService
when :following, :blocking, :muting, :lists
target_acct = @data['acct']
target_domain = domain(target_acct)
@target_account = stoplight_wrapper(target_domain).run { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) }
@target_account = stoplight_wrapper(target_domain).run(stoplight_fallback) { ResolveAccountService.new.call(target_acct, { check_delivery_availability: true }) }
return false if @target_account.nil?
when :bookmarks
target_uri = @data['uri']
@ -18,7 +21,7 @@ class BulkImportRowService
@target_status = ActivityPub::TagManager.instance.uri_to_resource(target_uri, Status)
return false if @target_status.nil? && ActivityPub::TagManager.instance.local_uri?(target_uri)
@target_status ||= stoplight_wrapper(target_domain).run { ActivityPub::FetchRemoteStatusService.new.call(target_uri) }
@target_status ||= stoplight_wrapper(target_domain).run(stoplight_fallback) { ActivityPub::FetchRemoteStatusService.new.call(target_uri) }
return false if @target_status.nil?
end
@ -51,13 +54,18 @@ class BulkImportRowService
TagManager.instance.local_domain?(domain) ? nil : TagManager.instance.normalize_domain(domain)
end
def stoplight_fallback
->(error) {}
end
def stoplight_wrapper(domain)
if domain.present?
Stoplight("source:#{domain}")
.with_fallback { nil }
.with_threshold(1)
.with_cool_off_time(5.minutes.seconds)
.with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) }
Stoplight(
"source:#{domain}",
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_THRESHOLD,
tracked_errors: [HTTP::Error, OpenSSL::SSL::SSLError]
)
else
Stoplight('domain-blank')
end

View File

@ -5,8 +5,8 @@ class ActivityPub::DeliveryWorker
include RoutingHelper
include JsonLdHelper
STOPLIGHT_COOL_OFF_TIME = 60
STOPLIGHT_FAILURE_THRESHOLD = 10
STOPLIGHT_COOLDOWN = 60
sidekiq_options queue: 'push', retry: 16, dead: false
@ -75,9 +75,11 @@ class ActivityPub::DeliveryWorker
end
def stoplight_wrapper
Stoplight(@inbox_url)
.with_threshold(STOPLIGHT_FAILURE_THRESHOLD)
.with_cool_off_time(STOPLIGHT_COOLDOWN)
Stoplight(
@inbox_url,
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_FAILURE_THRESHOLD
)
end
def failure_tracker

View File

@ -3,6 +3,8 @@
require 'stoplight'
Rails.application.reloader.to_prepare do
Stoplight.default_data_store = Stoplight::DataStore::Redis.new(RedisConnection.new.connection)
Stoplight.default_notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)]
Stoplight.configure do |config|
config.data_store = Stoplight::DataStore::Redis.new(RedisConnection.new.connection)
config.notifiers = [Stoplight::Notifier::Logger.new(Rails.logger)]
end
end

View File

@ -73,8 +73,8 @@ module Paperclip
@url_generator.for_as_default(style_name)
end
STOPLIGHT_COOL_OFF_TIME = 30
STOPLIGHT_THRESHOLD = 10
STOPLIGHT_COOLDOWN = 30
# We overwrite this method to put a circuit breaker around
# calls to object storage, to stop hitting APIs that are slow
@ -84,11 +84,12 @@ module Paperclip
# Don't go through Stoplight if we don't have anything object-storage-oriented to do
return super if @queued_for_delete.empty? && @queued_for_write.empty? && !dirty?
Stoplight('object-storage')
.with_threshold(STOPLIGHT_THRESHOLD)
.with_cool_off_time(STOPLIGHT_COOLDOWN)
.with_error_handler { |error, handle| error.is_a?(Seahorse::Client::NetworkingError) ? handle.call(error) : raise(error) }
.run { super }
Stoplight(
'object-storage',
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_THRESHOLD,
tracked_errors: [Seahorse::Client::NetworkingError]
).run { super }
end
end
end