Skip to content

Commit a8537b1

Browse files
authored
Add support for clear and update deployment broadcasts (#1864)
More focused events, and use the information from the event instead of reloading data.
1 parent 2dba144 commit a8537b1

File tree

5 files changed

+90
-16
lines changed

5 files changed

+90
-16
lines changed

lib/nerves_hub/devices.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ defmodule NervesHub.Devices do
739739
|> Ecto.Changeset.put_change(:deployment_id, deployment.id)
740740
|> Repo.update!()
741741

742-
_ = broadcast(device, "devices/updated")
742+
_ = broadcast(device, "devices/deployment-updated", %{deployment_id: deployment.id})
743743

744744
Map.put(device, :deployment, deployment)
745745
end
@@ -752,7 +752,7 @@ defmodule NervesHub.Devices do
752752
|> Ecto.Changeset.put_change(:deployment_id, nil)
753753
|> Repo.update!()
754754

755-
_ = broadcast(device, "devices/updated")
755+
_ = broadcast(device, "devices/deployment-cleared")
756756

757757
Map.put(device, :deployment, nil)
758758
end
@@ -1126,11 +1126,13 @@ defmodule NervesHub.Devices do
11261126
end
11271127
end
11281128

1129-
defp broadcast(%Device{id: id}, event) do
1129+
defp broadcast(device, event), do: broadcast(device, event, %{})
1130+
1131+
defp broadcast(%Device{id: id}, event, payload) do
11301132
Phoenix.PubSub.broadcast(
11311133
NervesHub.PubSub,
11321134
"device:#{id}",
1133-
%Phoenix.Socket.Broadcast{event: event}
1135+
%Phoenix.Socket.Broadcast{event: event, payload: payload}
11341136
)
11351137
end
11361138

lib/nerves_hub_web/channels/device_channel.ex

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,22 @@ defmodule NervesHubWeb.DeviceChannel do
163163
{:noreply, socket}
164164
end
165165

166-
@decorate with_span("Channels.DeviceChannel.handle_info:clear-deployment")
166+
@decorate with_span("Channels.DeviceChannel.handle_info:deployment-cleared")
167167
def handle_info(
168-
%Broadcast{event: "devices/clear-deployment"},
168+
%Broadcast{event: "devices/deployment-cleared"},
169169
%{assigns: %{device: device}} = socket
170170
) do
171-
device = %{device | deployment_id: nil, deployment: nil}
171+
device = %{device | deployment_id: nil}
172+
173+
{:noreply, update_device(socket, device)}
174+
end
175+
176+
@decorate with_span("Channels.DeviceChannel.handle_info:deployment-updated")
177+
def handle_info(
178+
%Broadcast{event: "devices/deployment-updated", payload: %{deployment_id: deployment_id}},
179+
%{assigns: %{device: device}} = socket
180+
) do
181+
device = %{device | deployment_id: deployment_id}
172182

173183
{:noreply, update_device(socket, device)}
174184
end
@@ -380,15 +390,19 @@ defmodule NervesHubWeb.DeviceChannel do
380390
:ok
381391
end
382392

383-
defp subscribe(topic) do
393+
defp subscribe(topic) when not is_nil(topic) do
384394
_ = Phoenix.PubSub.subscribe(NervesHub.PubSub, topic)
385395
:ok
386396
end
387397

388-
defp unsubscribe(topic) do
398+
defp subscribe(nil), do: :ok
399+
400+
defp unsubscribe(topic) when not is_nil(topic) do
389401
Phoenix.PubSub.unsubscribe(NervesHub.PubSub, topic)
390402
end
391403

404+
defp unsubscribe(nil), do: :ok
405+
392406
defp device_internal_broadcast!(socket, device, event, payload) do
393407
topic = "device:#{device.identifier}:internal"
394408
socket.endpoint.broadcast_from!(self(), topic, event, payload)
@@ -464,8 +478,6 @@ defmodule NervesHubWeb.DeviceChannel do
464478
defp deployment_channel(device) do
465479
if device.deployment_id do
466480
"deployment:#{device.deployment_id}"
467-
else
468-
"deployment:none"
469481
end
470482
end
471483

test/nerves_hub/devices_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ defmodule NervesHub.DevicesTest do
787787
end
788788

789789
describe "update_deployment/2" do
790-
test "updates deployment and broadcasts 'devices/updated'", %{
790+
test "updates deployment and broadcasts 'devices/deployment-updated'", %{
791791
device: device,
792792
deployment: deployment
793793
} do
@@ -797,12 +797,12 @@ defmodule NervesHub.DevicesTest do
797797
device = Devices.update_deployment(device, deployment)
798798

799799
assert device.deployment_id == deployment.id
800-
assert_receive %{event: "devices/updated"}
800+
assert_receive %{event: "devices/deployment-updated"}
801801
end
802802
end
803803

804804
describe "clear_deployment1/2" do
805-
test "clears deployment and broadcasts 'devices/updated'", %{
805+
test "clears deployment and broadcasts 'devices/deployment-cleared'", %{
806806
device: device,
807807
deployment: deployment
808808
} do
@@ -812,7 +812,7 @@ defmodule NervesHub.DevicesTest do
812812
device = Devices.clear_deployment(device)
813813

814814
refute device.deployment_id
815-
assert_receive %{event: "devices/updated"}
815+
assert_receive %{event: "devices/deployment-cleared"}
816816
end
817817
end
818818
end

test/nerves_hub_web/channels/device_channel_test.exs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ defmodule NervesHubWeb.DeviceChannelTest do
44

55
import TrackerHelper
66

7+
alias NervesHub.Devices
78
alias NervesHub.Fixtures
89
alias NervesHubWeb.DeviceChannel
910
alias NervesHubWeb.DeviceSocket
@@ -130,6 +131,63 @@ defmodule NervesHubWeb.DeviceChannelTest do
130131
assert device.latest_connection.metadata["connection_types"] == ["ethernet", "wifi"]
131132
end
132133

134+
test "deployment information is updated when the deployment is cleared" do
135+
user = Fixtures.user_fixture()
136+
{device, _firmware, deployment} = device_fixture(user, %{identifier: "123"})
137+
Devices.update_deployment(device, deployment)
138+
139+
%{db_cert: certificate, cert: _cert} = Fixtures.device_certificate_fixture(device)
140+
141+
{:ok, socket} =
142+
connect(DeviceSocket, %{}, connect_info: %{peer_data: %{ssl_cert: certificate.der}})
143+
144+
{:ok, _join_reply, socket} =
145+
subscribe_and_join(socket, DeviceChannel, "device")
146+
147+
refute is_nil(socket.assigns.device.deployment_id)
148+
refute is_nil(socket.assigns.deployment_channel)
149+
150+
Devices.clear_deployment(device)
151+
152+
# we need to let the channel process all messages before we can
153+
# check the state of the device's connection types
154+
socket = :sys.get_state(socket.channel_pid)
155+
156+
assert is_nil(socket.assigns.device.deployment_id)
157+
assert is_nil(socket.assigns.deployment_channel)
158+
end
159+
160+
test "deployment information is updated when the device joins a new deployment" do
161+
user = Fixtures.user_fixture()
162+
{device, firmware, deployment} = device_fixture(user, %{identifier: "123"})
163+
Devices.update_deployment(device, deployment)
164+
165+
%{db_cert: certificate, cert: _cert} = Fixtures.device_certificate_fixture(device)
166+
167+
{:ok, socket} =
168+
connect(DeviceSocket, %{}, connect_info: %{peer_data: %{ssl_cert: certificate.der}})
169+
170+
{:ok, _join_reply, socket} =
171+
subscribe_and_join(socket, DeviceChannel, "device")
172+
173+
assert socket.assigns.device.deployment_id == deployment.id
174+
refute is_nil(socket.assigns.deployment_channel)
175+
176+
device = NervesHub.Repo.preload(device, :org)
177+
178+
new_deployment =
179+
Fixtures.deployment_fixture(device.org, firmware, %{name: "Super Deployment"})
180+
181+
Devices.update_deployment(device, new_deployment)
182+
183+
# we need to let the channel process all messages before we can
184+
# check the state of the device's connection types
185+
socket = :sys.get_state(socket.channel_pid)
186+
187+
assert socket.assigns.device.deployment_id == new_deployment.id
188+
refute is_nil(socket.assigns.deployment_channel)
189+
end
190+
133191
describe "unhandled messages are caught" do
134192
test "handle_info" do
135193
user = Fixtures.user_fixture()

test/nerves_hub_web/live/devices/show_test.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ defmodule NervesHubWeb.Live.Devices.ShowTest do
578578
end)
579579
|> assert_has("div", text: "Eligible Deployments")
580580

581+
assert_receive %Phoenix.Socket.Broadcast{event: "devices/deployment-cleared"}
582+
581583
refute Repo.reload(device) |> Map.get(:deployment_id)
582584
end
583585

@@ -667,7 +669,7 @@ defmodule NervesHubWeb.Live.Devices.ShowTest do
667669
render_change(view, "set-deployment", %{"deployment_id" => deployment.id})
668670
end)
669671

670-
assert_receive %Phoenix.Socket.Broadcast{event: "devices/updated"}
672+
assert_receive %Phoenix.Socket.Broadcast{event: "devices/deployment-updated"}
671673
end
672674
end
673675

0 commit comments

Comments
 (0)