# frozen_string_literal: true module Streams # Assegna un StreamNode a una nuova sessione (least-loaded tra i ready). # Garantisce il nodo "home" derivato dagli ENV MediaMTX attuali. class NodeRegistry class NoCapacityError < StandardError; end HOME_SLUG = "home" class << self def ensure_home_from_env! StreamNode.find_or_initialize_by(slug: HOME_SLUG).tap do |node| node.assign_attributes( hostname: home_hostname, role: "home", status: "ready", provider: "local", rtmp_base_url: MatchLiveTv.mediamtx_rtmp_url, hls_base_url: MatchLiveTv.hls_public_url, api_base_url: MatchLiveTv.mediamtx_api_url, internal_rtmp_url: ENV.fetch("MEDIAMTX_INTERNAL_RTMP_URL", "rtmp://mediamtx:1935"), internal_hls_url: ENV.fetch("MEDIAMTX_HLS_URL", "http://mediamtx:8888"), max_publishers: ENV.fetch("STREAM_NODE_HOME_MAX_PUBLISHERS", "6").to_i, max_relays: ENV.fetch("STREAM_NODE_HOME_MAX_RELAYS", "6").to_i ) node.save! end end def allocate! ensure_home_from_env! node = StreamNode.ready .to_a .select(&:allocatable?) .min_by { |n| [n.active_publishers, n.role == "home" ? 1 : 0, n.slug] } raise NoCapacityError, "Nessun nodo streaming con slot liberi" if node.nil? node end private def home_hostname ENV["STREAM_NODE_HOME_HOSTNAME"].presence || begin uri = URI.parse(MatchLiveTv.mediamtx_rtmp_url.sub(/\Artmps?:\/\//, "http://")) uri.host.presence rescue URI::InvalidURIError nil end || "home" end end end end