69 lines
1.8 KiB
Ruby
69 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'json'
|
|
require 'net/http'
|
|
require 'uri'
|
|
|
|
class TournamentSyncPusher
|
|
class SyncFailed < StandardError; end
|
|
DEFAULT_HTTP_TIMEOUT = 5
|
|
|
|
def self.push!(tournament)
|
|
new(tournament).push!
|
|
end
|
|
|
|
def self.push_snapshot!(tournament, snapshot)
|
|
new(tournament).push_snapshot!(snapshot)
|
|
end
|
|
|
|
def initialize(tournament)
|
|
@tournament = tournament
|
|
end
|
|
|
|
def push!
|
|
return false unless tournament.sync_push_enabled?
|
|
|
|
push_snapshot!(TournamentSnapshotBuilder.build(tournament))
|
|
end
|
|
|
|
def push_snapshot!(snapshot)
|
|
response = perform_request(snapshot:)
|
|
|
|
raise SyncFailed, "sync push failed with status #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
|
|
|
|
tournament.update_columns(sync_last_pushed_at: Time.current, sync_last_push_error: nil)
|
|
true
|
|
rescue SyncFailed => e
|
|
tournament.update_columns(sync_last_push_error: e.message)
|
|
raise
|
|
rescue StandardError => e
|
|
tournament.update_columns(sync_last_push_error: e.message)
|
|
raise SyncFailed, e.message
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :tournament
|
|
|
|
def perform_request(snapshot:)
|
|
uri = URI.parse(tournament.sync_target_url)
|
|
request = Net::HTTP::Patch.new(uri)
|
|
request['accept'] = 'application/json'
|
|
request['content-type'] = 'application/json'
|
|
request['authorization'] = "Bearer #{tournament.sync_auth_token}"
|
|
request.body = JSON.dump({ snapshot: })
|
|
|
|
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
|
timeout = http_timeout_seconds
|
|
http.open_timeout = timeout
|
|
http.read_timeout = timeout
|
|
http.write_timeout = timeout if http.respond_to?(:write_timeout=)
|
|
http.request(request)
|
|
end
|
|
end
|
|
|
|
def http_timeout_seconds
|
|
ENV.fetch('TOURNAMENT_SYNC_HTTP_TIMEOUT_SECONDS', DEFAULT_HTTP_TIMEOUT).to_i
|
|
end
|
|
end
|