main
rb 26 lines 1.18 KB
Raw
1 # frozen_string_literal: true
2
3 # Syncs one mirror repository from its upstream. Enqueued on a schedule by
4 # MirrorSyncSchedulerJob and (optionally) by a GitHub push webhook. Marks the
5 # repo's sync status so the UI can show last-synced time and surface failures.
6 class MirrorSyncJob < ApplicationJob
7 queue_as :default
8
9 def perform(repository_id)
10 repo = Repository.find_by(id: repository_id)
11 return if repo.nil? || !repo.mirror?
12
13 repo.update!(mirror_status: "syncing")
14 MirrorSyncService.sync(repo)
15 repo.update!(mirror_status: "ok", mirror_synced_at: Time.current, mirror_error: nil)
16 rescue ImportUrlValidator::InvalidUrl => e
17 # Upstream now resolves somewhere unsafe (e.g. DNS rebinding) — stop, don't
18 # fetch, and surface it.
19 repo&.update!(mirror_status: "failed", mirror_error: "Upstream is no longer a valid public URL: #{e.message}")
20 rescue MirrorSyncService::SyncError => e
21 repo&.update!(mirror_status: "failed", mirror_error: e.message)
22 rescue StandardError => e
23 Rails.logger.error("Mirror sync failed for repo #{repository_id}: #{e.class}: #{e.message}")
24 repo&.update!(mirror_status: "failed", mirror_error: "Sync failed unexpectedly.")
25 end
26 end