Packages
livebook
0.10.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/system_resources.ex
defmodule Livebook.SystemResources do
@moduledoc false
# Periodically computes system resource usage.
@type memory :: %{total: non_neg_integer(), free: non_neg_integer()}
use GenServer
@name __MODULE__
@doc """
Returns system memory.
"""
@spec memory() :: memory()
def memory do
:ets.lookup_element(@name, :memory, 2)
end
@doc """
Subscribes to resource usage updates.
## Messages
* `{:memory_update, memory}`
"""
@spec subscribe() :: :ok | {:error, term()}
def subscribe() do
Phoenix.PubSub.subscribe(Livebook.PubSub, "system_resources")
end
@doc """
Updates the resources kept by this process.
"""
@spec update() :: :ok
def update do
GenServer.cast(@name, :update)
end
@doc false
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: @name)
end
@impl true
def init(:ok) do
:ets.new(@name, [:set, :named_table, :protected])
measure()
schedule()
{:ok, %{}}
end
@impl true
def handle_info(:measure, state) do
measure()
schedule()
{:noreply, state}
end
@impl true
def handle_cast(:update, state) do
memory = measure()
Phoenix.PubSub.local_broadcast(Livebook.PubSub, "system_resources", {:memory_update, memory})
{:noreply, state}
end
defp measure() do
memory_data = :memsup.get_system_memory_data()
free_memory = free_memory(Map.new(memory_data))
memory = %{total: memory_data[:total_memory], free: free_memory}
:ets.insert(@name, {:memory, memory})
memory
end
defp free_memory(%{available_memory: available}), do: available
defp free_memory(%{cached_memory: cached, buffered_memory: buffered, free_memory: free}) do
cached + buffered + free
end
defp free_memory(%{free_memory: free}), do: free
defp free_memory(_), do: 0
defp schedule() do
Process.send_after(self(), :measure, 15000)
end
end