From e7aeaf9fc10c685d4b23bca2f8329aa9e4972dd4 Mon Sep 17 00:00:00 2001 From: Josh Kalderimis Date: Tue, 29 Oct 2024 15:05:35 +1300 Subject: [PATCH] Remove an extra Deployment preload during `after_join` (#1618) - Preload the deployment, along with its firmware and archive, at the start of `after_join` - Preload all the required bits again in `Deployments.set_deployment` - And only use `:force` if the deployment has changed. - This approach saves 100ms during `after_join`, which is over 15% of the total time. --- lib/nerves_hub/deployments.ex | 19 ++++++++++--------- lib/nerves_hub/devices.ex | 7 +++++++ lib/nerves_hub_web/channels/device_channel.ex | 13 ++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/nerves_hub/deployments.ex b/lib/nerves_hub/deployments.ex index aefc525e1..19b3594e1 100644 --- a/lib/nerves_hub/deployments.ex +++ b/lib/nerves_hub/deployments.ex @@ -6,6 +6,7 @@ defmodule NervesHub.Deployments do alias NervesHub.AuditLogs alias NervesHub.Deployments.Deployment alias NervesHub.Deployments.InflightDeploymentCheck + alias NervesHub.Devices alias NervesHub.Devices.Device alias NervesHub.Products.Product alias NervesHub.Repo @@ -498,10 +499,8 @@ defmodule NervesHub.Deployments do [deployment] -> device - |> Ecto.Changeset.change() - |> Ecto.Changeset.put_change(:deployment_id, deployment.id) - |> Repo.update!() - |> Repo.preload([:deployment]) + |> Devices.update_deployment(deployment) + |> preload_with_firmware_and_archive(true) [deployment | _] -> Logger.debug( @@ -509,14 +508,16 @@ defmodule NervesHub.Deployments do ) device - |> Ecto.Changeset.change() - |> Ecto.Changeset.put_change(:deployment_id, deployment.id) - |> Repo.update!() - |> Repo.preload([:deployment]) + |> Devices.update_deployment(deployment) + |> preload_with_firmware_and_archive(true) end end def set_deployment(device) do - Repo.preload(device, [:deployment]) + preload_with_firmware_and_archive(device) + end + + def preload_with_firmware_and_archive(device, force \\ false) do + Repo.preload(device, [deployment: [:archive, :firmware]], force: force) end end diff --git a/lib/nerves_hub/devices.ex b/lib/nerves_hub/devices.ex index 083bc1aeb..5b17a284f 100644 --- a/lib/nerves_hub/devices.ex +++ b/lib/nerves_hub/devices.ex @@ -839,6 +839,13 @@ defmodule NervesHub.Devices do def matches_deployment?(_, _), do: false + def update_deployment(device, deployment) do + device + |> Ecto.Changeset.change() + |> Ecto.Changeset.put_change(:deployment_id, deployment.id) + |> Repo.update!() + end + @spec failure_threshold_met?(Device.t(), Deployment.t()) :: boolean() def failure_threshold_met?(%Device{} = device, %Deployment{} = deployment) do Enum.count(device.update_attempts) >= deployment.device_failure_threshold diff --git a/lib/nerves_hub_web/channels/device_channel.ex b/lib/nerves_hub_web/channels/device_channel.ex index 7c2676d2e..fa06b93c8 100644 --- a/lib/nerves_hub_web/channels/device_channel.ex +++ b/lib/nerves_hub_web/channels/device_channel.ex @@ -32,11 +32,7 @@ defmodule NervesHubWeb.DeviceChannel do end def handle_info({:after_join, params}, %{assigns: %{device: device}} = socket) do - device = - device - |> Devices.verify_deployment() - |> Deployments.set_deployment() - |> deployment_preload() + device = maybe_update_deployment(device) maybe_send_public_keys(device, socket, params) @@ -476,6 +472,13 @@ defmodule NervesHubWeb.DeviceChannel do :ok end + defp maybe_update_deployment(device) do + device + |> Deployments.preload_with_firmware_and_archive() + |> Devices.verify_deployment() + |> Deployments.set_deployment() + end + defp log_to_sentry(device, message, extra \\ %{}) do Sentry.Context.set_tags_context(%{ device_identifier: device.identifier,