Elimina i path MediaMTX orfani dopo ogni diretta.
Corregge il cleanup dei path live/match_{uuid}, rimuove sempre il path a fine sessione e lo esegue ogni ora via cron.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
94
backend/app/services/mediamtx/cleanup_orphan_paths.rb
Normal file
94
backend/app/services/mediamtx/cleanup_orphan_paths.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Mediamtx
|
||||
# Rimuove path MediaMTX live/match_{uuid} lasciati attivi dopo fine diretta.
|
||||
class CleanupOrphanPaths
|
||||
Result = Struct.new(:removed, :skipped, keyword_init: true)
|
||||
|
||||
SESSION_PATH = %r{\Alive/match_([0-9a-f-]{36})(?:_air)?\z}i
|
||||
|
||||
ACTIVE_SESSION_STATUSES = %w[live paused connecting reconnecting].freeze
|
||||
PROCESSING_GRACE = -> { ENV.fetch("RECORDINGS_LOCAL_PROCESSING_GRACE_HOURS", "6").to_i.hours }
|
||||
|
||||
def initialize(client: Client.new, logger: Rails.logger)
|
||||
@client = client
|
||||
@logger = logger
|
||||
@removed = 0
|
||||
@skipped = 0
|
||||
@deleted_session_ids = Set.new
|
||||
end
|
||||
|
||||
def call
|
||||
online = @client.online_path_names
|
||||
|
||||
@client.list_paths.each do |item|
|
||||
name = item["name"].to_s
|
||||
session_id = session_id_from_path(name)
|
||||
unless session_id
|
||||
@skipped += 1
|
||||
next
|
||||
end
|
||||
|
||||
if online.include?(name) || item["online"]
|
||||
@skipped += 1
|
||||
next
|
||||
end
|
||||
|
||||
next unless removable?(session_id)
|
||||
|
||||
remove_session_paths(session_id, name)
|
||||
end
|
||||
|
||||
Result.new(removed: @removed, skipped: @skipped)
|
||||
end
|
||||
|
||||
def removable?(session_id)
|
||||
session = StreamSession.find_by(id: session_id)
|
||||
return true if session.nil?
|
||||
|
||||
return false if ACTIVE_SESSION_STATUSES.include?(session.status)
|
||||
|
||||
recording = Recording.find_by(stream_session: session)
|
||||
return true if recording.nil?
|
||||
|
||||
return false if recording.status == "processing" && processing_within_grace?(session)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def session_id_from_path(path_name)
|
||||
match = path_name.match(SESSION_PATH)
|
||||
match&.[](1)
|
||||
end
|
||||
|
||||
def processing_within_grace?(session)
|
||||
ended_at = session.ended_at || session.updated_at
|
||||
ended_at.nil? || ended_at >= PROCESSING_GRACE.call.ago
|
||||
end
|
||||
|
||||
def remove_session_paths(session_id, path_name)
|
||||
return if @deleted_session_ids.include?(session_id)
|
||||
|
||||
session = StreamSession.find_by(id: session_id)
|
||||
if session
|
||||
@client.delete_path(session)
|
||||
else
|
||||
delete_orphan_path_names(session_id)
|
||||
end
|
||||
|
||||
@deleted_session_ids.add(session_id)
|
||||
@removed += 1
|
||||
@logger.info("[Mediamtx::CleanupOrphanPaths] removed paths for session #{session_id} (from #{path_name})")
|
||||
rescue Client::Error, Faraday::Error => e
|
||||
@skipped += 1
|
||||
@logger.warn("[Mediamtx::CleanupOrphanPaths] skip #{path_name}: #{e.message}")
|
||||
end
|
||||
|
||||
def delete_orphan_path_names(session_id)
|
||||
@client.delete_path_name("live/match_#{session_id}")
|
||||
@client.delete_path_name("live/match_#{session_id}_air")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -12,11 +12,8 @@ module Sessions
|
||||
complete_youtube_broadcast! if @session.youtube_broadcast_id.present?
|
||||
|
||||
recording = Recordings::FinalizeSession.new(@session).call
|
||||
if recording
|
||||
Recordings::UploadJob.perform_async(@session.id)
|
||||
else
|
||||
Mediamtx::Client.new.delete_path(@session)
|
||||
end
|
||||
Recordings::UploadJob.perform_async(@session.id) if recording
|
||||
remove_mediamtx_paths!
|
||||
|
||||
log_event("ended")
|
||||
SessionChannel.broadcast_message(@session, { type: "stream_event", event: "ended" })
|
||||
@@ -35,6 +32,12 @@ module Sessions
|
||||
@session.stream_events.create!(event_type: type, occurred_at: Time.current, metadata: {})
|
||||
end
|
||||
|
||||
def remove_mediamtx_paths!
|
||||
Mediamtx::Client.new.delete_path(@session)
|
||||
rescue Mediamtx::Client::Error => e
|
||||
Rails.logger.warn("[Sessions::Stop] delete_path #{@session.id}: #{e.message}")
|
||||
end
|
||||
|
||||
def complete_youtube_broadcast!
|
||||
Youtube::BroadcastService.new(@session.match.team).complete_broadcast!(@session.youtube_broadcast_id)
|
||||
rescue Youtube::BroadcastService::Error => e
|
||||
|
||||
Reference in New Issue
Block a user