Skip to content

Commit 40f8c66

Browse files
committed
Simplify restore
1 parent 1294a67 commit 40f8c66

3 files changed

Lines changed: 36 additions & 13 deletions

File tree

packages/sync-service/lib/electric/replication/shape_log_collector.ex

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -270,23 +270,22 @@ defmodule Electric.Replication.ShapeLogCollector do
270270

271271
{partitions, event_router, layers, count} =
272272
state.stack_id
273-
|> Electric.ShapeCache.ShapeStatus.list_shapes()
273+
|> Electric.ShapeCache.ShapeStatus.list_shapes_with_ids()
274274
|> Enum.reduce(
275275
{state.partitions, state.event_router, state.dependency_layers, 0},
276-
fn {shape_handle, shape}, {partitions, event_router, layers, count} = acc ->
277-
with {:ok, shape_id} <-
278-
Electric.ShapeCache.ShapeStatus.id_for_handle(state.stack_id, shape_handle),
279-
{:ok, dependency_ids} <- dependency_ids(state.stack_id, shape) do
280-
restore_shape(
281-
{shape_handle, shape_id, shape, dependency_ids},
282-
{partitions, event_router, layers, count}
283-
)
284-
else
285-
# The shape (or one of its dependencies) has no id mapping in
286-
# ShapeStatus, e.g. it's mid-removal. Skip it.
276+
fn {shape_handle, shape_id, shape}, {partitions, event_router, layers, count} = acc ->
277+
case dependency_ids(state.stack_id, shape) do
278+
{:ok, dependency_ids} ->
279+
restore_shape(
280+
{shape_handle, shape_id, shape, dependency_ids},
281+
{partitions, event_router, layers, count}
282+
)
283+
284+
# A dependency has no id mapping in ShapeStatus, e.g. it's
285+
# mid-removal. Skip this shape.
287286
:error ->
288287
Logger.warning(
289-
"Skipping shape during restore: no id mapping",
288+
"Skipping shape during restore: dependency has no id mapping",
290289
shape_handle: shape_handle
291290
)
292291

packages/sync-service/lib/electric/shape_cache/shape_status.ex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ defmodule Electric.ShapeCache.ShapeStatus do
154154
end)
155155
end
156156

157+
@doc """
158+
Like `list_shapes/1` but also returns each shape's in-memory `shape_id`.
159+
"""
160+
@spec list_shapes_with_ids(stack_id()) :: [{shape_handle(), shape_id(), Shape.t()}]
161+
def list_shapes_with_ids(stack_id) when is_stack_id(stack_id) do
162+
stack_id
163+
|> list_shapes()
164+
|> Enum.flat_map(fn {handle, shape} ->
165+
case id_for_handle(stack_id, handle) do
166+
{:ok, id} -> [{handle, id, shape}]
167+
:error -> []
168+
end
169+
end)
170+
end
171+
157172
@spec topological_sort([{shape_handle(), Shape.t()}]) :: [{shape_handle(), Shape.t()}]
158173
defp topological_sort(handles_and_shapes, acc \\ [], visited \\ MapSet.new())
159174
defp topological_sort([], acc, _visited), do: Enum.reverse(acc) |> List.flatten()

packages/sync-service/test/electric/shape_cache/shape_status_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,15 @@ defmodule Electric.ShapeCache.ShapeStatusTest do
449449
assert is_integer(restored_id)
450450
assert {:ok, ^handle} = ShapeStatus.handle_for_id(stack_id, restored_id)
451451
end
452+
453+
test "list_shapes_with_ids returns each shape's handle, id and shape", %{stack_id: stack_id} do
454+
{:ok, {handle1, id1}} = ShapeStatus.add_shape(stack_id, shape!())
455+
{:ok, {handle2, id2}} = ShapeStatus.add_shape(stack_id, shape2!())
456+
457+
result = ShapeStatus.list_shapes_with_ids(stack_id) |> Enum.sort_by(&elem(&1, 1))
458+
459+
assert [{^handle1, ^id1, %Shape{}}, {^handle2, ^id2, %Shape{}}] = result
460+
end
452461
end
453462

454463
defp shape!, do: shape!("test")

0 commit comments

Comments
 (0)