Skip to content

Commit 595c13a

Browse files
joshkjjcarstens
andauthored
Remove the need to get a connection before updating it (#1835)
This rejigs the `device_heartbeat` function a little, moving the broadcast into the function and out of the socket. This also removes the `Repo.get!`, instead using `Repo.update_all` An Ecto `join` has been added so we can fetch the device identifier to use for the broadcast. --------- Co-authored-by: Jon Carstens <[email protected]>
1 parent a9884a8 commit 595c13a

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

lib/nerves_hub/devices/connections.ex

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,27 @@ defmodule NervesHub.Devices.Connections do
6363
@doc """
6464
Updates the `last_seen_at`field for a device connection with current timestamp
6565
"""
66-
@spec device_heartbeat(UUIDv7.t()) :: {:ok, DeviceConnection.t()} | {:error, Ecto.Changeset.t()}
67-
def device_heartbeat(ref_id) do
68-
DeviceConnection
69-
|> Repo.get!(ref_id)
70-
|> DeviceConnection.update_changeset(%{last_seen_at: DateTime.utc_now()})
71-
|> Repo.update()
66+
@spec device_heartbeat(UUIDv7.t()) :: :ok
67+
def device_heartbeat(id) do
68+
{1, [result]} =
69+
DeviceConnection
70+
|> join(:inner, [dc], d in assoc(dc, :device), as: :device)
71+
|> select([device: device], %{identifier: device.identifier})
72+
|> where([dc], dc.id == ^id)
73+
|> Repo.update_all(
74+
set: [
75+
status: "connected",
76+
last_seen_at: DateTime.utc_now()
77+
]
78+
)
79+
80+
Phoenix.Channel.Server.broadcast_from!(
81+
NervesHub.PubSub,
82+
self(),
83+
"device:#{result.identifier}:internal",
84+
"connection:heartbeat",
85+
%{}
86+
)
7287
end
7388

7489
@doc """

lib/nerves_hub_web/channels/device_socket.ex

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,9 @@ defmodule NervesHubWeb.DeviceSocket do
4646
end
4747

4848
@decorate with_span("Channels.DeviceSocket.heartbeat")
49-
defp heartbeat(
50-
%Phoenix.Socket.Message{topic: "phoenix", event: "heartbeat"},
51-
%{
52-
assigns: %{
53-
reference_id: ref_id,
54-
device: device
55-
}
56-
} = socket
57-
) do
49+
defp heartbeat(%Phoenix.Socket.Message{topic: "phoenix", event: "heartbeat"}, socket) do
5850
if heartbeat?(socket) do
59-
{:ok, _device_connection} = Connections.device_heartbeat(ref_id)
60-
61-
_ =
62-
socket.endpoint.broadcast_from(
63-
self(),
64-
"device:#{device.identifier}:internal",
65-
"connection:heartbeat",
66-
%{}
67-
)
51+
Connections.device_heartbeat(socket.assigns.reference_id)
6852

6953
last_heartbeat =
7054
DateTime.utc_now()

test/nerves_hub/devices/connections_test.exs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ defmodule NervesHub.Devices.ConnectionsTest do
2626
end
2727

2828
test "device heartbeat", %{device: device} do
29-
assert {:ok, %DeviceConnection{id: connection_id, last_seen_at: first_seen_at}} =
29+
assert {:ok, %DeviceConnection{id: connection_id, last_seen_at: first_seen_at} = connection} =
3030
Connections.device_connected(device.id)
3131

32-
assert {:ok,
33-
%DeviceConnection{id: ^connection_id, last_seen_at: last_seen_at, status: :connected}} =
34-
Connections.device_heartbeat(connection_id)
32+
Connections.device_heartbeat(connection_id)
33+
34+
%DeviceConnection{id: ^connection_id, last_seen_at: last_seen_at, status: :connected} =
35+
Repo.reload(connection)
3536

3637
assert last_seen_at > first_seen_at
3738
assert %DeviceConnection{status: :connected} = Connections.get_latest_for_device(device.id)

0 commit comments

Comments
 (0)