namespace :streams do desc "Termina sessioni attive non in onda su MediaMTX e rimuove path RTMP orfani" task cleanup_stale: :environment do client = Mediamtx::Client.new online = client.online_path_names stale = StreamSession.broadcasting.includes(match: :team).reject do |session| online.include?(session.mediamtx_path_name) end puts "MediaMTX online: #{online.size}" puts "Sessioni da chiudere: #{stale.size}" stale.each do |session| Sessions::Stop.new(session).call puts " ended #{session.id} (#{session.match.team.name} vs #{session.match.opponent_name})" rescue StandardError => e session.finish! if session.may_finish? client.delete_path(session) if session.mediamtx_path_name.present? puts " ended #{session.id} (fallback: #{e.message})" end removed = cleanup_orphan_mediamtx_paths(client, online) puts "Path MediaMTX rimossi: #{removed}" puts "Fatto." end end def cleanup_orphan_mediamtx_paths(client, online_paths) removed = 0 client.list_paths.each do |item| name = item["name"] next unless name&.start_with?("match_") session_id = name.delete_prefix("match_") session = StreamSession.find_by(id: session_id) should_remove = !online_paths.include?(name) && (session.nil? || %w[ended error].include?(session.status)) next unless should_remove client.delete_path_name(name) removed += 1 puts " deleted path #{name}" rescue Mediamtx::Client::Error, Faraday::Error => e puts " skip #{name}: #{e.message}" end removed end