Skip to content

Commit

Permalink
Emit live_component update events
Browse files Browse the repository at this point in the history
  • Loading branch information
bamorim committed Nov 12, 2023
1 parent 04722f1 commit 4d05ee5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 8 deletions.
38 changes: 30 additions & 8 deletions lib/phoenix_live_view/diff.ex
Original file line number Diff line number Diff line change
Expand Up @@ -659,17 +659,39 @@ defmodule Phoenix.LiveView.Diff do
end)

assigns_sockets = Enum.reverse(assigns_sockets)
metadata = Enum.reverse(metadata)
update_many? = function_exported?(component, :update_many, 1)

component_data=
assigns_sockets
|> Enum.zip(metadata)
|> Enum.map(fn {{assigns, socket}, {cid, _id, new?}} ->
%{
assigns: assigns,
socket: socket,
cid: cid,
new?: new?
}
end)

telemetry_metadata = %{socket: socket, component: component, component_data: component_data, update_many?: update_many?}

sockets =
if function_exported?(component, :update_many, 1) do
component.update_many(assigns_sockets)
else
Enum.map(assigns_sockets, fn {assigns, socket} ->
Utils.maybe_call_update!(socket, component, assigns)
end)
end
:telemetry.span([:phoenix, :live_component, :update], telemetry_metadata, fn ->
sockets =
if update_many? do
component.update_many(assigns_sockets)
else
Enum.map(assigns_sockets, fn {assigns, socket} ->
Utils.maybe_call_update!(socket, component, assigns)
end)
end

component_data = sockets |> Enum.zip(component_data) |> Enum.map(fn {socket, data} -> %{data | socket: socket} end)

{sockets, Map.put(telemetry_metadata, :component_data, component_data)}
end)

metadata = Enum.reverse(metadata)
triplet = zip_components(sockets, metadata, component, cids, {pending, diffs, components})
{triplet, seen_ids}
end)
Expand Down
38 changes: 38 additions & 0 deletions test/phoenix_live_view/integrations/telemetry_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,44 @@ defmodule Phoenix.LiveView.TelemtryTest do
assert metadata.component == Phoenix.LiveViewTest.StatefulComponent
assert metadata.params == %{"op" => "boom"}
end

test "emits telemetry events for update calls", %{conn: conn} do
attach_telemetry([:phoenix, :live_component, :update])

{:ok, view, _html} = live(conn, "/multi-targets")

assert_receive {:event, [:phoenix, :live_component, :update, :start], %{system_time: _},
metadata}

assert metadata.socket
assert metadata.component == Phoenix.LiveViewTest.StatefulComponent

assert [
%{
cid: cid,
assigns: %{id: _id, name: name},
socket: component_socket,
new?: true
},
_
] = metadata.component_data

assert is_integer(cid)

assert_receive {:event, [:phoenix, :live_component, :update, :stop], %{duration: _},

Check failure on line 279 in test/phoenix_live_view/integrations/telemetry_test.exs

View workflow job for this annotation

GitHub Actions / mix test (OTP 24.3 | Elixir 1.13.4)

test live components emits telemetry events for update calls (Phoenix.LiveView.TelemetryTest)

Check failure on line 279 in test/phoenix_live_view/integrations/telemetry_test.exs

View workflow job for this annotation

GitHub Actions / mix test (OTP 25.3 | Elixir 1.15.4)

test live components emits telemetry events for update calls (Phoenix.LiveView.TelemetryTest)
metadata}

assert metadata.socket
assert metadata.component == Phoenix.LiveViewTest.StatefulComponent
assert [%{socket: updated_component_socket}, _] = metadata.component_data

assert updated_component_socket != component_socket

render_click(view, "disable", %{"name" => name})

assert_receive {:event, [:phoenix, :live_component, :update, :start], %{system_time: _},
%{component_data: [%{new?: false, assigns: %{name: name, disabled: true}}]}}
end
end

describe "logging configuration" do
Expand Down
4 changes: 4 additions & 0 deletions test/support/live_views/components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ defmodule Phoenix.LiveViewTest.WithMultipleTargets do
def handle_event("transform", %{"op" => _op}, socket) do
{:noreply, assign(socket, :message, "Parent was updated")}
end

def handle_event("disable", %{"name" => name}, socket) do
{:noreply, assign(socket, :disabled, Enum.uniq([name | socket.assigns.disabled]))}
end
end

defmodule Phoenix.LiveViewTest.WithLogOverride do
Expand Down

0 comments on commit 4d05ee5

Please sign in to comment.