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>
95 lines
2.6 KiB
Ruby
95 lines
2.6 KiB
Ruby
# 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
|