dawarich/app/jobs/tracks/boundary_resolver_job.rb
2025-08-29 13:59:46 +02:00

61 lines
1.7 KiB
Ruby

# frozen_string_literal: true
# Resolves cross-chunk track boundaries and finalizes parallel track generation
# Runs after all chunk processors complete to handle tracks spanning multiple chunks
class Tracks::BoundaryResolverJob < ApplicationJob
queue_as :tracks
def perform(user_id, session_id)
@user = User.find(user_id)
@session_manager = Tracks::SessionManager.new(user_id, session_id)
return unless session_exists_and_ready?
boundary_tracks_resolved = resolve_boundary_tracks
finalize_session(boundary_tracks_resolved)
rescue StandardError => e
ExceptionReporter.call(e, "Failed to resolve boundaries for user #{user_id}")
mark_session_failed(e.message)
end
private
attr_reader :user, :session_manager
def session_exists_and_ready?
return false unless session_manager.session_exists?
unless session_manager.all_chunks_completed?
reschedule_boundary_resolution
return false
end
true
end
def resolve_boundary_tracks
boundary_detector = Tracks::BoundaryDetector.new(user)
boundary_detector.resolve_cross_chunk_tracks
end
def finalize_session(boundary_tracks_resolved)
session_data = session_manager.get_session_data
total_tracks = session_data['tracks_created'] + boundary_tracks_resolved
session_manager.mark_completed
end
def reschedule_boundary_resolution
# Reschedule with exponential backoff (max 5 minutes)
delay = [30.seconds, 1.minute, 2.minutes, 5.minutes].sample
self.class.set(wait: delay).perform_later(user.id, session_manager.session_id)
end
def mark_session_failed(error_message)
session_manager.mark_failed(error_message)
end
end