Prepara l'architettura multi-nodo (MediaMTX+ffmpeg) con assignment URL per sessione, admin di provision/drain e provider Cloud/DNS astratti verso mltv-stream.net. Co-authored-by: Cursor <cursoragent@cursor.com>
39 lines
1.2 KiB
Ruby
39 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Nodo streaming (MediaMTX [+ relay ffmpeg]). Fase 0: registry + assignment URL.
|
|
class StreamNode < ApplicationRecord
|
|
ROLES = %w[home cloud lab].freeze
|
|
STATUSES = %w[provisioning ready draining offline error].freeze
|
|
PROVIDERS = %w[local proxmox_lab hetzner].freeze
|
|
|
|
has_many :stream_sessions, dependent: :nullify
|
|
|
|
validates :slug, presence: true, uniqueness: true
|
|
validates :hostname, presence: true
|
|
validates :role, inclusion: { in: ROLES }
|
|
validates :status, inclusion: { in: STATUSES }
|
|
validates :provider, inclusion: { in: PROVIDERS }
|
|
validates :rtmp_base_url, :hls_base_url, :api_base_url, presence: true
|
|
validates :max_publishers, :max_relays, numericality: { greater_than: 0 }
|
|
|
|
scope :ready, -> { where(status: "ready") }
|
|
scope :allocatable, -> { ready }
|
|
|
|
# Sessioni che occupano uno slot path MediaMTX su questo nodo.
|
|
def occupying_sessions
|
|
stream_sessions.where(status: %w[idle connecting live reconnecting paused])
|
|
end
|
|
|
|
def active_publishers
|
|
occupying_sessions.count
|
|
end
|
|
|
|
def free_slots
|
|
[max_publishers - active_publishers, 0].max
|
|
end
|
|
|
|
def allocatable?
|
|
status == "ready" && free_slots.positive?
|
|
end
|
|
end
|