Skip to content
This repository has been archived by the owner on Jun 11, 2023. It is now read-only.

Commit

Permalink
Add type specifications on TOP
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomassaro committed Nov 8, 2017
1 parent 235e78d commit 5aa3209
Show file tree
Hide file tree
Showing 28 changed files with 548 additions and 194 deletions.
15 changes: 2 additions & 13 deletions lib/hardware/internal/motherboard.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ defmodule Helix.Hardware.Internal.Motherboard do
end
end

@spec fetch_by_nip(Network.id, NetworkConnection.ip) ::
@spec fetch_by_nip(Network.id, Network.ip) ::
Motherboard.t
| nil
def fetch_by_nip(network_id, ip) do
Expand Down Expand Up @@ -128,18 +128,7 @@ defmodule Helix.Hardware.Internal.Motherboard do
end

@spec resources(Motherboard.t) ::
%{
cpu: non_neg_integer,
ram: non_neg_integer,
hdd: non_neg_integer,
net: %{
Network.id =>
%{
uplink: non_neg_integer,
downlink: non_neg_integer
}
}
}
Motherboard.resources
def resources(motherboard) do
components_ids = get_components_ids(motherboard)

Expand Down
15 changes: 15 additions & 0 deletions lib/hardware/model/motherboard.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Helix.Hardware.Model.Motherboard do
import Ecto.Changeset

alias Ecto.Changeset
alias Helix.Network.Model.Network
alias Helix.Hardware.Model.Component
alias Helix.Hardware.Model.ComponentSpec
alias Helix.Hardware.Model.MotherboardSlot
Expand All @@ -23,6 +24,20 @@ defmodule Helix.Hardware.Model.Motherboard do
updated_at: NaiveDateTime.t
}

@type resources ::
%{
cpu: non_neg_integer,
ram: non_neg_integer,
hdd: non_neg_integer,
net: %{
Network.id =>
%{
uplink: non_neg_integer,
downlink: non_neg_integer
}
}
}

@primary_key false
schema "motherboards" do
field :motherboard_id, Component.ID,
Expand Down
39 changes: 26 additions & 13 deletions lib/process/action/process.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule Helix.Process.Action.Process do

alias Helix.Event
alias Helix.Entity.Model.Entity
alias Helix.Entity.Query.Entity, as: EntityQuery
alias Helix.Network.Model.Connection
Expand All @@ -25,16 +26,22 @@ defmodule Helix.Process.Action.Process do

@type base_params ::
%{
:gateway_id => Server.idtb,
:target_id => Server.idtb,
:gateway_id => Server.id,
:target_id => Server.id,
:data => Processable.t,
:type => String.t,
optional(:file_id) => File.idtb | nil,
optional(:network_id) => Network.idtb | nil,
optional(:connection_id) => Connection.idtb | nil,
optional(:objective) => map
} | term

:type => Process.type,
:file_id => File.id | nil,
:network_id => Network.id | nil,
:connection_id => Connection.id | nil,
:objective => map,
:l_dynamic => Process.dynamic,
:r_dynamic => Process.dynamic,
:static => Process.static
}

@spec create(base_params) ::
{:ok, Process.t, [ProcessCreatedEvent.t]}
| {:error, Process.changeset}
def create(params) do
with \
source_entity = EntityQuery.fetch_by_server(params.gateway_id),
Expand All @@ -51,6 +58,8 @@ defmodule Helix.Process.Action.Process do
end
end

@spec delete(Process.t, Process.kill_reason) ::
{:ok, [ProcessCompletedEvent.t]}
def delete(process = %Process{}, reason) do
ProcessInternal.delete(process)

Expand All @@ -73,6 +82,8 @@ defmodule Helix.Process.Action.Process do
# {:ok, [event]}
# end

@spec signal(Process.t, Process.signal, Process.signal_params) ::
{:ok, [Event.t]}
def signal(process = %Process{}, signal, params \\ %{}) do
{action, events} = signal_handler(signal, process, params)

Expand All @@ -81,6 +92,8 @@ defmodule Helix.Process.Action.Process do
{:ok, events ++ [signaled_event]}
end

@spec signal_handler(Process.signal, Process.t, Process.signal_params) ::
{Processable.action, [Event.t]}
defp signal_handler(:SIGTERM, process, _),
do: Processable.complete(process.data, process)

Expand All @@ -103,14 +116,16 @@ defmodule Helix.Process.Action.Process do
# do: Processable.file_deleted(process.data, process, file)

@spec prepare_create_params(base_params, Entity.id) ::
Process.create_params
Process.creation_params
defp prepare_create_params(params, source_entity_id),
do: Map.put(params, :source_entity_id, source_entity_id)

@spec get_process_ips(base_params) ::
{gateway_ip :: Network.ip, target_ip :: Network.ip}
| {nil, nil}
defp get_process_ips(params = %{network_id: _}) do
defp get_process_ips(%{network_id: nil}),
do: {nil, nil}
defp get_process_ips(params) do
gateway_ip = ServerQuery.get_ip(params.gateway_id, params.network_id)

target_ip =
Expand All @@ -122,6 +137,4 @@ defmodule Helix.Process.Action.Process do

{gateway_ip, target_ip}
end
defp get_process_ips(_),
do: {nil, nil}
end
37 changes: 35 additions & 2 deletions lib/process/action/top.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,42 @@ defmodule Helix.Process.Action.TOP do
alias Helix.Event
alias Helix.Server.Model.Server
alias Helix.Process.Action.Process, as: ProcessAction
alias Helix.Process.Internal.Process, as: ProcessInternal
alias Helix.Process.Model.Process
alias Helix.Process.Model.Processable
alias Helix.Process.Model.TOP
alias Helix.Process.Query.Process, as: ProcessQuery
alias Helix.Process.Query.TOP, as: TOPQuery

alias Helix.Process.Event.TOP.BringMeToLife, as: TOPBringMeToLifeEvent
alias Helix.Process.Event.TOP.Recalcado, as: TOPRecalcadoEvent

@type recalque_result ::
{:ok, [Process.t], [TOPRecalcadoEvent.t]}
| {:error, :resources}

@typep recalque_opts :: term

@spec complete(Process.t) ::
{:ok, [Event.t]}
| {:error, {:process, :running}}
def complete(process) do
case TOP.Scheduler.simulate(process) do
{:completed, _process} ->
ProcessAction.signal(process, :SIGTERM, %{reason: :completed})

{:running, _process} ->
{:error, {:process, :running}, []}
{:error, {:process, :running}}
end
end

@spec recalque(Server.id, recalque_opts) ::
recalque_result
@spec recalque(Process.t, recalque_opts) ::
%{
gateway: recalque_result,
target: recalque_result
}
def recalque(process_or_server, alloc_opts \\ [])

def recalque(%Process{gateway_id: gateway_id, target_id: target_id}, opts) do
Expand All @@ -34,6 +52,8 @@ defmodule Helix.Process.Action.TOP do
def recalque(server_id = %Server.ID{}, opts),
do: do_recalque(server_id, opts)

@spec do_recalque(Server.id, recalque_opts) ::
recalque_result
defp do_recalque(server_id, alloc_opts) do
resources = TOPQuery.load_top_resources(server_id)
processes = ProcessQuery.get_processes_on_server(server_id)
Expand All @@ -50,6 +70,8 @@ defmodule Helix.Process.Action.TOP do
end
end

@spec schedule(TOP.Allocator.allocation_successful) ::
[Process.t]
defp schedule(%{allocated: processes, dropped: _dropped}) do
# Organize all processes in two groups: the local ones and the remote ones
# A local process was started on this very server, while a remote process
Expand Down Expand Up @@ -119,6 +141,8 @@ defmodule Helix.Process.Action.TOP do
processes
end

@spec handle_forecast(TOP.Scheduler.forecast) ::
term
docp """
`handle_forecast` aggregates the `Scheduler.forecast/1` result and guides it
to the corresponding handlers. Check `handle_completed/1` and `handle_next/1`
Expand All @@ -129,6 +153,8 @@ defmodule Helix.Process.Action.TOP do
handle_next(next)
end

@spec handle_completed([Process.t]) ::
term
docp """
`handle_completed` receives processes that according to `Schedule.forecast/1`
have already finished. We'll then complete each one and Emit their
Expand All @@ -145,6 +171,8 @@ defmodule Helix.Process.Action.TOP do
within our architecture, are not supposed to emit events. However,
`handle_completed` happens within a spawned process, and as such the resulting
events cannot be sent back to the original Handler/ActionFlow caller.
Emits event.
"""
defp handle_completed([]),
do: :noop
Expand All @@ -156,13 +184,17 @@ defmodule Helix.Process.Action.TOP do
end)
end

@spec handle_next({Process.t, Process.time_left}) ::
term
docp """
`handle_next` will receive the "next-to-be-completed" process, as defined by
`Scheduler.forecast/1`. If a tuple is received, then we know there's a process
that will be completed soon, and we'll sleep during the remaining time.
Once the process is (supposedly) completed, TOP will receive the
`TOPBringMeToLifeEvent`, which shall confirm the completion and actually
complete the task.
Emits TOPBringMeToLifeEvent.t after `time_left` seconds have elapsed.
"""
defp handle_next({process, time_left}) do
wake_me_up = TOPBringMeToLifeEvent.new(process)
Expand All @@ -174,7 +206,8 @@ defmodule Helix.Process.Action.TOP do
defp handle_next(_),
do: :noop

alias Helix.Process.Internal.Process, as: ProcessInternal
@spec handle_checkpoint([Process.t]) ::
term
docp """
`handle_checkpoint` is responsible for handling the result of
`Scheduler.checkpoint/1`, called during the `recalque` above.
Expand Down
18 changes: 9 additions & 9 deletions lib/process/event/handler/top.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ defmodule Helix.Process.Event.Handler.TOP do
Event.emit(events)

# Can't wake up
{:error, {:process, :running}, []} ->
# This shouldn't happen... recalculate the TOP just in case
{:error, {:process, :running}} ->
# Weird but could happen. Recalculate the TOP just in case
call_recalque(process)
end
end
Expand All @@ -44,33 +44,33 @@ defmodule Helix.Process.Event.Handler.TOP do
def recalque_handler(%_{confirmed: true}),
do: :noop

@spec call_recalque(Process.t) ::
{gateway_recalque :: boolean, target_recalque :: boolean}
defp call_recalque(process = %Process{}) do
%{gateway: gateway_recalque, target: target_recalque} =
TOPAction.recalque(process)

gateway_recalque =
case gateway_recalque do
{:ok, processes, events} ->
{:ok, _processes, events} ->
Event.emit(events)

{true, processes}
true

_ ->
false
end

target_recalque =
case target_recalque do
{:ok, processes, events} ->
{:ok, _processes, events} ->
Event.emit(events)

{true, processes}
true

_ ->
false
end

{true, :todo}
{gateway_recalque, target_recalque}
end

def connection_closed(event = %ConnectionClosedEvent{}) do
Expand Down
3 changes: 3 additions & 0 deletions lib/process/executable.ex
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ defmodule Helix.Process.Executable do

{:error, %Ecto.Changeset{}} ->
{:error, :internal}

_ ->
{:error, :internal}
end
end
end
Expand Down
5 changes: 4 additions & 1 deletion lib/process/internal/process.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ defmodule Helix.Process.Internal.Process do
alias Helix.Process.Model.Process
alias Helix.Process.Repo

@spec create(Process.creation_params) ::
{:ok, Process.t}
| {:error, Process.changeset}
def create(params) do
params
|> Process.create_changeset()
Expand All @@ -29,7 +32,7 @@ defmodule Helix.Process.Internal.Process do
|> Enum.map(&Process.format/1)
end

@spec get_running_processes_of_type_on_server(Server.idt, String.t) ::
@spec get_running_processes_of_type_on_server(Server.idt, Process.type) ::
[Process.t]
def get_running_processes_of_type_on_server(gateway_id, type) do
gateway_id
Expand Down
Loading

0 comments on commit 5aa3209

Please sign in to comment.