defmodule Object.ResourceManager do @moduledoc """ Manages system resources including memory, CPU, network, and storage limits. Provides graceful degradation and emergency shutdown capabilities. """ defstruct [ :memory_limit, :cpu_limit, :network_limit, :storage_limit, :graceful_degradation, :emergency_shutdown_threshold, current_usage: %{memory: 0, cpu: 0.0, network: 0, storage: 0}, alerts: [], emergency_mode: false ] def new(opts) do %__MODULE__{ memory_limit: opts[:memory_limit] || 1000, cpu_limit: opts[:cpu_limit] || 100.0, network_limit: opts[:network_limit] || 10000, storage_limit: opts[:storage_limit] || 5000, graceful_degradation: opts[:graceful_degradation] || true, emergency_shutdown_threshold: opts[:emergency_shutdown_threshold] || 0.95 } end def check_resource_usage(resource_manager) do memory_usage = :erlang.memory(:total) / 1024 / 1024 cpu_usage = get_cpu_usage() current_usage = %{ memory: memory_usage, cpu: cpu_usage, network: 0, storage: 0 } resource_manager = %{resource_manager | current_usage: current_usage} memory_pressure = memory_usage / resource_manager.memory_limit cpu_pressure = cpu_usage / resource_manager.cpu_limit pressure = max(memory_pressure, cpu_pressure) cond do pressure >= resource_manager.emergency_shutdown_threshold -> trigger_emergency_shutdown(resource_manager) pressure >= 0.8 -> trigger_graceful_degradation(resource_manager) true -> {resource_manager, :normal} end end defp get_cpu_usage do case :cpu_sup.avg1() / 256 do usage when usage >= 0 -> usage _ -> 0.0 end rescue _ -> 0.0 end defp trigger_emergency_shutdown(resource_manager) do resource_manager = %{resource_manager | emergency_mode: true, alerts: ["Emergency shutdown triggered" | resource_manager.alerts] } {resource_manager, :emergency_shutdown} end defp trigger_graceful_degradation(resource_manager) do resource_manager = %{resource_manager | alerts: ["Graceful degradation activated" | resource_manager.alerts] } {resource_manager, :graceful_degradation} end def get_memory_pressure(resource_manager) do resource_manager.current_usage.memory / resource_manager.memory_limit end def allocate_resource(resource_manager, resource_type, amount) do current = resource_manager.current_usage[resource_type] || 0 limit = Map.get(resource_manager, :"#{resource_type}_limit", 1000) if current + amount <= limit do new_usage = Map.put(resource_manager.current_usage, resource_type, current + amount) {:ok, %{resource_manager | current_usage: new_usage}} else {:error, :resource_limit_exceeded} end end def deallocate_resource(resource_manager, resource_type, amount) do current = resource_manager.current_usage[resource_type] || 0 new_amount = max(0, current - amount) new_usage = Map.put(resource_manager.current_usage, resource_type, new_amount) %{resource_manager | current_usage: new_usage} end end