Skip to content

Commit

Permalink
Improve error handling on availability router
Browse files Browse the repository at this point in the history
  • Loading branch information
zacksiri committed Jan 30, 2025
1 parent 9e0dcb7 commit a4f37b3
Show file tree
Hide file tree
Showing 10 changed files with 2,379 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
erlang 26.2.5.6
erlang 26.2.5
elixir 1.16.3-otp-26
caddy 2.7.4
4 changes: 2 additions & 2 deletions lib/uplink/availability.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ defmodule Uplink.Availability do
to: Requirement.Manager,
as: :process

@spec check!(list(%Requirement{})) ::
{:ok, list(%Resource{})} | {:error, any()}
def check!(requirements) when is_list(requirements) do
case get_monitor() do
%{"attributes" => _attributes} = monitor ->
Expand Down Expand Up @@ -90,8 +92,6 @@ defmodule Uplink.Availability do

inputs = Enum.reduce(resources, template, &to_inputs(&1, &2, requirements))

IO.inspect(inputs)

predictions = Opsmo.predict(Opsmo.CRPM, inputs)

resources
Expand Down
2 changes: 2 additions & 0 deletions lib/uplink/availability/placeability.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ defmodule Uplink.Availability.Placeability do
use Ecto.Schema
import Ecto.Changeset

@derive Jason.Encoder

@primary_key false
embedded_schema do
field :cpu, :decimal
Expand Down
51 changes: 29 additions & 22 deletions lib/uplink/availability/requirement/manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,41 @@ defmodule Uplink.Availability.Requirement.Manager do
alias Uplink.Clients.LXD

alias Uplink.Availability.Requirement
alias Uplink.Availability.Requirement.Params

def process(params) do
%{"project" => project, "cpu" => cpu, "memory" => memory, "disk" => disk} =
params
case Params.parse(params) do
{:ok, %Params{} = params} ->
instance_names =
LXD.list_instances(project: params.project)
|> Enum.map(fn instance ->
instance.name
end)

instance_names =
LXD.list_instances(project: project)
|> Enum.map(fn instance ->
instance.name
end)
requirements =
LXD.list_cluster_members()
|> Enum.map(fn member ->
LXD.get_node(member.server_name)
end)
|> Enum.map(fn node ->
%{
"node" => node.name,
"instances" => instance_names,
"cpu" => normalize(params.cpu, node.cpu_cores_count),
"memory" => normalize(params.memory, node.total_memory),
"disk" => normalize(params.disk, node.total_storage)
}
end)
|> Enum.map(&Requirement.parse(&1))

LXD.list_cluster_members()
|> Enum.map(fn member ->
LXD.get_node(member.server_name)
end)
|> Enum.map(fn node ->
%{
"node" => node.name,
"instances" => instance_names,
"cpu" => normalize(cpu, node.cpu_cores_count),
"memory" => normalize(memory, node.total_memory),
"disk" => normalize(disk, node.total_storage)
}
end)
|> Enum.map(&Requirement.parse(&1))
{:ok, requirements}

{:error, changeset} ->
{:error, changeset}
end
end

defp normalize(required, total) do
Decimal.div(Decimal.new(required), Decimal.new(total))
Decimal.div(required, Decimal.new(total))
end
end
23 changes: 23 additions & 0 deletions lib/uplink/availability/requirement/params.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Uplink.Availability.Requirement.Params do
use Ecto.Schema
import Ecto.Changeset

embedded_schema do
field :project, :string
field :cpu, :decimal
field :memory, :decimal
field :disk, :decimal
end

def changeset(params_struct, params) do
params_struct
|> cast(params, [:project, :cpu, :memory, :disk])
|> validate_required([:project, :cpu, :memory, :disk])
end

def parse(params) do
%__MODULE__{}
|> changeset(params)
|> apply_action(:insert)
end
end
13 changes: 7 additions & 6 deletions lib/uplink/availability/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ defmodule Uplink.Availability.Router do
"requirement" => requirement_params
} = conn.body_params

requirement_params
|> Availability.process_requirement()
|> Availability.check!()
|> case do
{:ok, resources} ->
json(conn, :ok, resources)
with {:ok, requirements} <-
Availability.process_requirement(requirement_params),
{:ok, resources} <- Availability.check!(requirements) do
json(conn, :ok, resources)
else
{:error, %Ecto.Changeset{} = error} ->
json(conn, :unprocessable_entity, handle_changeset(error))

{:error, reason} ->
json(conn, :service_unavailable, %{error: %{message: reason}})
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/lxd/cluster/members/arrakis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"type": "sync",
"status": "Success",
"status_code": 200,
"operation": "",
"error_code": 0,
"error": "",
"metadata": [
{
"roles": [
"database"
],
"failure_domain": "",
"description": "",
"config": null,
"server_name": "arrakis",
"url": "https://10.130.0.3:8443",
"database": true,
"status": "Online",
"message": "Fully operational",
"architecture": "x86_64"
}
]
}
Loading

0 comments on commit a4f37b3

Please sign in to comment.