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

Commit

Permalink
Add MotherboardUpdated and MotherboardUpdateFailed events
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomassaro committed Dec 16, 2017
1 parent 3fecf8d commit 7859e41
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 19 deletions.
2 changes: 2 additions & 0 deletions lib/event/dispatcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ defmodule Helix.Event.Dispatcher do
##############################################################################

# All
event ServerEvent.Motherboard.Updated
event ServerEvent.Motherboard.UpdateFailed
event ServerEvent.Server.Password.Acquired
event ServerEvent.Server.Joined

Expand Down
2 changes: 1 addition & 1 deletion lib/henforcer/henforcer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ defmodule Helix.Henforcer do
@spec is_b?(x) ::
{true, is_b_relay}
| is_b_error
| can_d_error
def is_b?(x)
def is_c?(y)
Expand Down Expand Up @@ -310,6 +309,7 @@ defmodule Helix.Henforcer do
case unquote(henforcer) do
{true, sub_relay} ->
{true, relay(unquote(relay), sub_relay)}

{false, reason, sub_relay} ->
{false, reason, relay(unquote(relay), sub_relay)}
end
Expand Down
28 changes: 27 additions & 1 deletion lib/server/action/flow/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ defmodule Helix.Server.Action.Flow.Server do
alias Helix.Server.Model.Motherboard
alias Helix.Server.Model.Server

alias Helix.Server.Event.Motherboard.Updated, as: MotherboardUpdatedEvent
alias Helix.Server.Event.Motherboard.UpdateFailed,
as: MotherboardUpdateFailedEvent

@spec setup(Server.type, Entity.t, Component.mobo, Event.relay) ::
{:ok, Server.t}
@doc """
Expand Down Expand Up @@ -63,18 +67,28 @@ defmodule Helix.Server.Action.Flow.Server do

{:ok, new_server} <- update_server_mobo(server, new_mobo_id)
do
emit_motherboard_updated(new_server, relay)

{:ok, new_server, new_motherboard}
else
_ ->
emit_motherboard_update_failed(server, :internal, relay)
end
end
end

def detach_mobo(server = %Server{}, motherboard = %Motherboard{}, _relay) do
def detach_mobo(server = %Server{}, motherboard = %Motherboard{}, relay) do
flowing do
with \
:ok <- MotherboardAction.detach(motherboard),
{:ok, new_server} <- ServerAction.detach(server)
do
emit_motherboard_updated(new_server, relay)

{:ok, new_server}
else
_ ->
emit_motherboard_update_failed(server, :internal, relay)
end
end
end
Expand All @@ -83,4 +97,16 @@ defmodule Helix.Server.Action.Flow.Server do
do: {:ok, server}
defp update_server_mobo(server, mobo_id),
do: ServerAction.attach(server, mobo_id)

defp emit_motherboard_updated(server, relay) do
server
|> MotherboardUpdatedEvent.new()
|> Event.emit(from: relay)
end

defp emit_motherboard_update_failed(server, reason, relay) do
server
|> MotherboardUpdateFailedEvent.new(reason)
|> Event.emit(from: relay)
end
end
90 changes: 90 additions & 0 deletions lib/server/event/motherboard.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
defmodule Helix.Server.Event.Motherboard do

import Helix.Event

event Updated do

alias Helix.Server.Model.Server
alias Helix.Server.Public.Index.Hardware, as: HardwareIndex

event_struct [:server, :index_cache]

def new(server = %Server{}) do
%__MODULE__{
server: server,

# `index_cache` is a cache of the new server hardware index (bootstrap)
# We save it on the event struct so it is only generated once;
# otherwise it would have to be recalculated to every player joined
# on the server channel.
# We save the full cache (`:local`) and, if the Notificable receiver is
# a remote server, we nilify the `:motherboard` entry
index_cache: HardwareIndex.index(server, :local)
}
end

notify do

@event :motherboard_updated

def generate_payload(event, %{assigns: %{meta: %{access_type: :local}}}) do
data = HardwareIndex.render_index(event.index_cache)

{:ok, data}
end

def generate_payload(event, %{assigns: %{meta: %{access_type: :remote}}}) do
data =
event.index_cache
|> HardwareIndex.render_index()
|> Map.replace(:motherboard, nil)

{:ok, data}
end

def whom_to_notify(event),
do: %{server: event.server.server_id}
end
end

event UpdateFailed do

alias Helix.Server.Model.Server

event_struct [:server_id, :reason]

@type t :: %__MODULE__{
server_id: Server.id,
reason: reason
}

@type reason :: :internal

@spec new(Server.idt, reason) ::
t
def new(server = %Server{}, reason),
do: new(server.server_id, reason)
def new(server_id = %Server.ID{}, reason) do
%__MODULE__{
server_id: server_id,
reason: reason
}
end

notify do

@event :motherboard_update_failed

def generate_payload(event, %{assigns: %{meta: %{access_type: :local}}}) do
data = %{reason: event.reason}

{:ok, data}
end
def generate_payload(_, _),
do: :noreply

def whom_to_notify(event),
do: %{server: event.server_id}
end
end
end
21 changes: 13 additions & 8 deletions lib/server/public/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ defmodule Helix.Server.Public.Index do
def gateway(server = %Server{}, entity_id) do
index = %{
password: server.password,
name: server.hostname
name: server.hostname,
hardware: HardwareIndex.index(server, :local)
}

Map.merge(server_common(server, entity_id), index)
Expand All @@ -242,10 +243,11 @@ defmodule Helix.Server.Public.Index do
Renderer for `gateway/2`
"""
def render_gateway(server) do
partial = %{
password: server.password,
name: server.name
}
partial =
%{
password: server.password,
name: server.name
}

Map.merge(partial, render_server_common(server))
end
Expand All @@ -261,7 +263,12 @@ defmodule Helix.Server.Public.Index do
- Resync client data with `bootstrap` request
"""
def remote(server = %Server{}, entity_id) do
server_common(server, entity_id)
index =
%{
hardware: HardwareIndex.index(server, :remote)
}

Map.merge(server_common(server, entity_id), index)
end

@spec render_remote(remote) ::
Expand All @@ -285,7 +292,6 @@ defmodule Helix.Server.Public.Index do
filesystem_index = FileIndex.index(server.server_id)
tunnel_index = NetworkIndex.index(server.server_id)
process_index = ProcessIndex.index(server.server_id, entity_id)
hardware_index = HardwareIndex.index(server)

main_storage_id =
server.server_id
Expand All @@ -297,7 +303,6 @@ defmodule Helix.Server.Public.Index do
logs: log_index,
main_storage: main_storage_id,
storages: filesystem_index,
hardware: hardware_index,
processes: process_index,
tunnels: tunnel_index
}
Expand Down
18 changes: 16 additions & 2 deletions lib/server/public/index/hardware.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,30 @@ defmodule Helix.Server.Public.Index.Hardware do
motherboard: MotherboardIndex.rendered_index | nil
}

@spec index(Server.t) ::
@typep access_type :: :local | :remote

@spec index(Server.t, access_type) ::
index
def index(server = %Server{}) do
def index(server = %Server{}, :local) do
%{
motherboard: MotherboardIndex.index(server)
}
end

def index(_server = %Server{}, :remote) do
%{
motherboard: nil
}
end

@spec render_index(index) ::
rendered_index
def render_index(index = %{motherboard: nil}) do
%{
motherboard: nil
}
end

def render_index(index) do
%{
motherboard: MotherboardIndex.render_index(index.motherboard)
Expand Down
10 changes: 5 additions & 5 deletions test/server/action/server_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ defmodule Helix.Server.Action.ServerTest do
{server1, _} = ServerSetup.server()
{server2, _} = ServerSetup.server()

assert {:error, cs} = ServerAction.attach(server1, server2.motherboard_id)
refute cs.valid?
assert {:error, reason} =
ServerAction.attach(server1, server2.motherboard_id)
assert reason == :internal

CacheHelper.sync_test()
end
Expand All @@ -53,9 +54,8 @@ defmodule Helix.Server.Action.ServerTest do

{mobo, _} = ComponentSetup.component(type: :mobo)

assert {:error, cs} = ServerAction.attach(server, mobo.component_id)

refute cs.valid?
assert {:error, reason} = ServerAction.attach(server, mobo.component_id)
assert reason == :internal

CacheHelper.sync_test()
end
Expand Down
34 changes: 34 additions & 0 deletions test/server/event/motherboard_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule Helix.Server.Event.MotherboardTest do

use Helix.Test.Case.Integration

alias Helix.Event.Notificable

alias Helix.Test.Channel.Setup, as: ChannelSetup
alias Helix.Test.Event.Setup, as: EventSetup

@socket_local ChannelSetup.mock_server_socket(access_type: :local)
@socket_remote ChannelSetup.mock_server_socket(access_type: :remote)

describe "MotherboardUpdatedEvent.generate_payload/2" do
test "generates full hardware index on gateway (local)" do
event = EventSetup.Server.motherboard_updated()

assert {:ok, data} = Notificable.generate_payload(event, @socket_local)

# Returns full data about the motherboard
assert data.motherboard.motherboard_id
assert data.motherboard.slots
assert data.motherboard.network_connections
end

test "generates partial hardware index on endpoint (remote)" do
event = EventSetup.Server.motherboard_updated()

assert {:ok, data} = Notificable.generate_payload(event, @socket_remote)

# Does not return information about the motherboard
refute data.motherboard
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule Helix.Server.Websocket.Channel.Server.Topics.MotherboardTest do

import Phoenix.ChannelTest
import Helix.Test.Macros
import Helix.Test.Channel.Macros

alias Helix.Entity.Action.Entity, as: EntityAction
alias Helix.Network.Action.Network, as: NetworkAction
Expand Down Expand Up @@ -83,7 +84,8 @@ defmodule Helix.Server.Websocket.Channel.Server.Topics.MotherboardTest do
# Empty response. It's async!
assert Enum.empty?(response.data)

# TODO: Test received the events
# Client received the MotherboardUpdatedEvent
wait_events [:motherboard_updated]

# But the underlying server components were modified!!!
motherboard = MotherboardQuery.fetch(server.motherboard_id)
Expand Down Expand Up @@ -136,7 +138,8 @@ defmodule Helix.Server.Websocket.Channel.Server.Topics.MotherboardTest do
# Empty response. It's async!
assert Enum.empty?(response.data)

# TODO: Test received the events
# Client received the MotherboardUpdatedEvent
wait_events [:motherboard_updated]

new_server = ServerQuery.fetch(server.server_id)

Expand Down
15 changes: 15 additions & 0 deletions test/support/event/setup/server.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Helix.Test.Event.Setup.Server do

alias Helix.Server.Model.Server

alias Helix.Server.Event.Motherboard.Updated, as: MotherboardUpdatedEvent

alias Helix.Test.Server.Setup, as: ServerSetup

def motherboard_updated(server = %Server{}),
do: MotherboardUpdatedEvent.new(server)
def motherboard_updated do
{server, _} = ServerSetup.server()
motherboard_updated(server)
end
end

0 comments on commit 7859e41

Please sign in to comment.