Skip to content

Conversation

@magnetised
Copy link
Contributor

No description provided.

@magnetised magnetised changed the title move snapshotters to separate supervisor [wip]: Speed up shutdown by brutally killing snapshot processes Jan 21, 2026
@codecov
Copy link

codecov bot commented Jan 21, 2026

❌ 55 Tests Failed:

Tests completed Failed Passed Skipped
2131 55 2076 0
View the top 3 failed test(s) by shortest run time
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 handles buffering multiple callers correctly
Stack Traces | 0s run time
18) test await_snapshot_start/4 handles buffering multiple callers correctly (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:689
     ** (EXIT from #PID<0.17633.0>) an exception was raised:

          match (=) failed
          code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
          left:  :started
          right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test await_snapshot_start/4 handles buffering multiple callers correctly", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17679.0>, :await_snapshot_start, 45000]}}}
          stacktrace:
            test/electric/shape_cache_test.exs:715: anonymous fn/3 in Electric.ShapeCacheTest."test await_snapshot_start/4 handles buffering multiple callers correctly"/1
            (elixir 1.19.1) lib/task/supervised.ex:105: Task.Supervised.invoke_mfa/2
            (elixir 1.19.1) lib/task/supervised.ex:40: Task.Supervised.reply/4
Elixir.Electric.Shapes.ConsumerTest::test event handling notifies live listeners when invalidated
Stack Traces | 0.013s run time
20) test event handling notifies live listeners when invalidated (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:514
     ** (exit) exited in: GenServer.call(#PID<0.12791.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling notifies live listeners when invalidated", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test event handling correctly writes only relevant changes to multiple shape logs
Stack Traces | 0.0152s run time
18) test event handling correctly writes only relevant changes to multiple shape logs (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:229
     ** (exit) exited in: GenServer.call(#PID<0.12920.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling correctly writes only relevant changes to multiple shape logs", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 returns :started for snapshots that have started
Stack Traces | 0.0164s run time
6) test await_snapshot_start/4 returns :started for snapshots that have started (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:660
     Assertion with == failed
     code:  assert ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id) == :started
     left:  {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test await_snapshot_start/4 returns :started for snapshots that have started", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.19038.0>, :await_snapshot_start, 45000]}}}
     right: :started
     stacktrace:
       test/electric/shape_cache_test.exs:668: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 shape initialization creates initial snapshot if one doesn't exist
Stack Traces | 0.0177s run time
2) test get_or_create_shape_handle/2 shape initialization creates initial snapshot if one doesn't exist (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:154
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 shape initialization creates initial snapshot if one doesn't exist", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.19259.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:168: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling doesn't append to log when change is irrelevant for active shapes
Stack Traces | 0.018s run time
22) test event handling doesn't append to log when change is irrelevant for active shapes (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:286
     ** (exit) exited in: GenServer.call(#PID<0.12677.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling doesn't append to log when change is irrelevant for active shapes", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test event handling notifies listeners of new changes
Stack Traces | 0.0197s run time
12) test event handling notifies listeners of new changes (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:394
     ** (exit) exited in: GenServer.call(#PID<0.13704.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling notifies listeners of new changes", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test event handling consumer crashing stops affected consumer
Stack Traces | 0.0202s run time
21) test event handling consumer crashing stops affected consumer (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:554
     ** (exit) exited in: GenServer.call(#PID<0.12734.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling consumer crashing stops affected consumer", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage ConsumerRegistry.enable_suspend should suspend hibernated consumers
Stack Traces | 0.0241s run time
10) test transaction handling with real storage ConsumerRegistry.enable_suspend should suspend hibernated consumers (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:912
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage ConsumerRegistry.enable_suspend should suspend hibernated consumers",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.13933.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:919: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling cleans shapes affected by a relation change
Stack Traces | 0.0243s run time
15) test event handling cleans shapes affected by a relation change (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:472
     ** (exit) exited in: GenServer.call(#PID<0.13379.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling cleans shapes affected by a relation change", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.ShapeCacheTest::test after restart waits until publication filters are restored
Stack Traces | 0.0246s run time
29) test after restart waits until publication filters are restored (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:987
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test after restart waits until publication filters are restored",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.17001.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle1, ctx.stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:990: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling cleans shapes affected by a relation rename
Stack Traces | 0.025s run time
6) test event handling cleans shapes affected by a relation rename (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:441
     ** (exit) exited in: GenServer.call(#PID<0.14285.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling cleans shapes affected by a relation rename", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage should hibernate not suspend if has dependencies
Stack Traces | 0.025s run time
19) test transaction handling with real storage should hibernate not suspend if has dependencies (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:859
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:shutdown, :cleanup},
           {GenServer, :call, [#PID<0.12859.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:868: (test)
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 propagates error in snapshot creation to listeners
Stack Traces | 0.027s run time
11) test await_snapshot_start/4 propagates error in snapshot creation to listeners (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:817
     ** (exit) exited in: :sys.get_state(#PID<0.18551.0>)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test await_snapshot_start/4 propagates error in snapshot creation to listeners", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     code: await_for_consumer_to_have_waiters(consumer_pid)
     stacktrace:
       (stdlib 7.1) sys.erl:755: :sys.send_system_msg/2
       (stdlib 7.1) sys.erl:344: :sys.get_state/1
       test/electric/shape_cache_test.exs:1186: Electric.ShapeCacheTest.await_for_consumer_to_have_waiters/2
       test/electric/shape_cache_test.exs:837: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling appends to log when xid >= xmin
Stack Traces | 0.0277s run time
16) test event handling appends to log when xid >= xmin (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:188
     ** (exit) exited in: GenServer.call(#PID<0.13259.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling appends to log when xid >= xmin", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.ShapeCacheTest::test list_shapes/1 lists the shape as active once there is a snapshot
Stack Traces | 0.0289s run time
14) test list_shapes/1 lists the shape as active once there is a snapshot (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:531
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test list_shapes/1 lists the shape as active once there is a snapshot", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17920.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:544: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once even with queued requests
Stack Traces | 0.0298s run time
10) test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once even with queued requests (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:220
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once even with queued requests", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.18609.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:259: (test)
Elixir.Electric.ShapeCacheTest::test after restart restores shapes with subqueries and their materializers
Stack Traces | 0.0301s run time
25) test after restart restores shapes with subqueries and their materializers (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:1042
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:shutdown, :cleanup},
           {GenServer, :call, [#PID<0.17252.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:1046: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage should terminate after :hibernate_after ms
Stack Traces | 0.0316s run time
8) test transaction handling with real storage should terminate after :hibernate_after ms (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:824
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage should terminate after :hibernate_after ms",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.14097.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:831: (test)
Elixir.Electric.ShapeCacheTest::test start_consumer_for_handle/2 starts a consumer plus dependencies
Stack Traces | 0.0324s run time
30) test start_consumer_for_handle/2 starts a consumer plus dependencies (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:1136
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:shutdown,
            {GenServer, :call,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test start_consumer_for_handle/2 starts a consumer plus dependencies",
                 {Electric.Shapes.Consumer.Materializer, "86050472-1769512353237040"}}},
               :subscribe,
               5000
             ]}}, {GenServer, :call, [#PID<0.16945.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:1140: (test)
Elixir.Electric.ShapeCacheTest::test after restart restores latest offset
Stack Traces | 0.0356s run time
20) test after restart restores latest offset (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:1012
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test after restart restores latest offset",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.17567.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:1015: (test)
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 should stop awaiting if shape process dies unexpectedly
Stack Traces | 0.0361s run time
19) test await_snapshot_start/4 should stop awaiting if shape process dies unexpectedly (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:845
     Assertion with in failed
     code:  assert error in [
              {:exited_with_reason, :some_reason},
              :unknown,
              "Shape terminated before snapshot was ready"
            ]
     left:  {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test await_snapshot_start/4 should stop awaiting if shape process dies unexpectedly", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17622.0>, :await_snapshot_start, 45000]}}
     right: [{:exited_with_reason, :some_reason}, :unknown, "Shape terminated before snapshot was ready"]
     stacktrace:
       test/electric/shape_cache_test.exs:870: (test)
Elixir.Electric.ShapeCacheTest::test has_shape?/2 returns true for known shape handle
Stack Traces | 0.0367s run time
27) test has_shape?/2 returns true for known shape handle (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:619
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test has_shape?/2 returns true for known shape handle", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17136.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:627: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once
Stack Traces | 0.0388s run time
17) test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:174
     match (=) failed
     The following variables were pinned:
       shape_handle = "95846100-1769512355923445"
     code:  assert {^shape_handle, _} = ShapeCache.get_or_create_shape_handle(@shape, ctx.stack_id)
     left:  {^shape_handle, _}
     right: {"95846100-1769512355927034", LogOffset.last_before_real_offsets()}
     stacktrace:
       test/electric/shape_cache_test.exs:208: anonymous fn/4 in Electric.ShapeCacheTest."test get_or_create_shape_handle/2 shape initialization triggers table prep and snapshot creation only once"/1
       (elixir 1.19.1) lib/enum.ex:4562: Enum.reduce_range/5
       test/electric/shape_cache_test.exs:206: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling does not clean shapes if relation didn't change
Stack Traces | 0.0406s run time
7) test event handling does not clean shapes if relation didn't change (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:416
     ** (exit) exited in: GenServer.call(#PID<0.14211.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling does not clean shapes if relation didn't change", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage should correctly normalize a flush boundary to txn
Stack Traces | 0.0474s run time
9) test transaction handling with real storage should correctly normalize a flush boundary to txn (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:757
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage should correctly normalize a flush boundary to txn",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.14044.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:763: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling handles truncate without appending to log
Stack Traces | 0.0517s run time
1) test event handling handles truncate without appending to log (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:312
     ** (exit) exited in: GenServer.call(#PID<0.15716.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling handles truncate without appending to log", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage terminating the consumers cleans up its entry from Storage ETS
Stack Traces | 0.0533s run time
11) test transaction handling with real storage terminating the consumers cleans up its entry from Storage ETS (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:972
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage terminating the consumers cleans up its entry from Storage ETS",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.13791.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:977: (test)
Elixir.Electric.ShapeCacheTest::test after restart restores shape_handles
Stack Traces | 0.0569s run time
7) test after restart restores shape_handles (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:978
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test after restart restores shape_handles",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.18983.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle1, ctx.stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:980: (test)
Elixir.Electric.ShapeCacheTest::test after restart restores shapes with subqueries and their materializers when backup missing
Stack Traces | 0.0587s run time
12) test after restart restores shapes with subqueries and their materializers when backup missing (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:1063
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:shutdown, :cleanup},
           {GenServer, :call, [#PID<0.18491.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       test/electric/shape_cache_test.exs:1067: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage should notify txns skipped because of xmin/xip as flushed
Stack Traces | 0.0592s run time
14) test transaction handling with real storage should notify txns skipped because of xmin/xip as flushed (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:787
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage should notify txns skipped because of xmin/xip as flushed",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.13501.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:795: (test)
Elixir.Electric.Shapes.ConsumerTest::test event handling handles truncate when shape has a where clause
Stack Traces | 0.0615s run time
2) test event handling handles truncate when shape has a where clause (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:368
     ** (exit) exited in: GenServer.call(#PID<0.15616.0>, :await_snapshot_start, 45000)
         ** (EXIT) exited in: PartitionSupervisor.partitions({:via, Registry, {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test event handling handles truncate when shape has a where clause", {Electric.Shapes.SnapshotterSupervisor, nil}}})
             ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
     stacktrace:
       (elixir 1.19.1) lib/gen_server.ex:1142: GenServer.call/3
       .../electric/shapes/consumer_test.exs:180: anonymous fn/3 in Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       (stdlib 7.1) maps.erl:894: :maps.fold_1/4
       .../electric/shapes/consumer_test.exs:162: Electric.Shapes.ConsumerTest.__ex_unit_setup_0_11/1
       Electric.Shapes.ConsumerTest.__ex_unit_describe_0/1
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 against real db can create shape from partitioned table
Stack Traces | 0.0689s run time
4) test get_or_create_shape_handle/2 against real db can create shape from partitioned table (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:468
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 against real db can create shape from partitioned table", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.19158.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:483: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage duplicate transactions storage is idempotent
Stack Traces | 0.0797s run time
4) test transaction handling with real storage duplicate transactions storage is idempotent (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:618
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage duplicate transactions storage is idempotent",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.15236.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:623: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 against real db crashes when initial snapshot query fails to return data quickly enough
Stack Traces | 0.081s run time
24) test get_or_create_shape_handle/2 against real db crashes when initial snapshot query fails to return data quickly enough (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:501
     match (=) failed
     code:  assert {:error, %Electric.SnapshotError{type: :slow_snapshot_query}} =
              ShapeCache.await_snapshot_start(shape_handle, stack_id)
     left:  {:error, %Electric.SnapshotError{type: :slow_snapshot_query}}
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 against real db crashes when initial snapshot query fails to return data quickly enough", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17328.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:513: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage restarting a consumer doesn't lower the last known offset when only snapshot is present
Stack Traces | 0.0912s run time
3) test transaction handling with real storage restarting a consumer doesn't lower the last known offset when only snapshot is present (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:725
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:noproc,
            {PartitionSupervisor, :partitions,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage restarting a consumer doesn't lower the last known offset when only snapshot is present",
                 {Electric.Shapes.SnapshotterSupervisor, nil}}}
             ]}}, {GenServer, :call, [#PID<0.15481.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:729: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage UPDATE during pending move-in is converted to INSERT and query result skips duplicate key
Stack Traces | 0.108s run time
13) test transaction handling with real storage UPDATE during pending move-in is converted to INSERT and query result skips duplicate key (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:995
     ** (MatchError) no match of right hand side value:

         {:error,
          {{:shutdown,
            {GenServer, :call,
             [
               {:via, Registry,
                {:"Electric.ProcessRegistry:Electric.Shapes.ConsumerTest test transaction handling with real storage UPDATE during pending move-in is converted to INSERT and query result skips duplicate key",
                 {Electric.Shapes.Consumer.Materializer, "26585834-1769512350441195"}}},
               :subscribe,
               5000
             ]}}, {GenServer, :call, [#PID<0.13625.0>, :await_snapshot_start, 45000]}}}

     code: :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     stacktrace:
       .../electric/shapes/consumer_test.exs:1027: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 against real db creates initial snapshot from DB data
Stack Traces | 0.11s run time
22) test get_or_create_shape_handle/2 against real db creates initial snapshot from DB data (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:347
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 against real db creates initial snapshot from DB data", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.17455.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:355: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 against real db uses correct display settings when querying initial data
Stack Traces | 0.12s run time
31) test get_or_create_shape_handle/2 against real db uses correct display settings when querying initial data (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:379
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 against real db uses correct display settings when querying initial data", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.16887.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:414: (test)
Elixir.Electric.ShapeCleanerTest::test remove_shape/2 cleans up shape data and rotates the shape handle
Stack Traces | 0.14s run time
6) test remove_shape/2 cleans up shape data and rotates the shape handle (Electric.ShapeCleanerTest)
     test/electric/shape_cleaner_test.exs:107
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCleanerTest test remove_shape/2 cleans up shape data and rotates the shape handle", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.2466.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cleaner_test.exs:120: (test)
Elixir.Electric.ShapeCleanerTest::test remove_shapes_for_relations/2 cleans up shape data for relevant shapes
Stack Traces | 0.143s run time
4) test remove_shapes_for_relations/2 cleans up shape data for relevant shapes (Electric.ShapeCleanerTest)
     test/electric/shape_cleaner_test.exs:225
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCleanerTest test remove_shapes_for_relations/2 cleans up shape data for relevant shapes", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.2945.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cleaner_test.exs:227: (test)
Elixir.Electric.ShapeCleanerTest::test remove_shape_async/2 cleans up shape data and rotates the shape handle
Stack Traces | 0.15s run time
1) test remove_shape_async/2 cleans up shape data and rotates the shape handle (Electric.ShapeCleanerTest)
     test/electric/shape_cleaner_test.exs:107
     match (=) failed
     code:  assert :started = ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  :started
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCleanerTest test remove_shape_async/2 cleans up shape data and rotates the shape handle", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.3915.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cleaner_test.exs:120: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 against real db correctly propagates the error
Stack Traces | 0.174s run time
32) test get_or_create_shape_handle/2 against real db correctly propagates the error (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:440
     match (=) failed
     code:  assert {:error, %Electric.SnapshotError{type: :schema_changed}} =
              ShapeCache.await_snapshot_start(shape_handle, ctx.stack_id)
     left:  {:error, %Electric.SnapshotError{type: :schema_changed}}
     right: {:error, {{:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 against real db correctly propagates the error", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}, {GenServer, :call, [#PID<0.16802.0>, :await_snapshot_start, 45000]}}}
     stacktrace:
       test/electric/shape_cache_test.exs:451: anonymous fn/2 in Electric.ShapeCacheTest."test get_or_create_shape_handle/2 against real db correctly propagates the error"/1
       (ex_unit 1.19.1) lib/ex_unit/capture_log.ex:121: ExUnit.CaptureLog.with_log/2
       test/electric/shape_cache_test.exs:448: (test)
Elixir.Electric.ShapeCacheTest::test count_shapes/1 returns the correct count of shapes
Stack Traces | 0.372s run time
13) test count_shapes/1 returns the correct count of shapes (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:589
     Assertion with == failed
     code:  assert num_shapes == ShapeCache.count_shapes(ctx.stack_id)
     left:  59
     right: 1
     stacktrace:
       test/electric/shape_cache_test.exs:604: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 should not return the same shape_handle for all columns and selected columns
Stack Traces | 0.414s run time
1) test get_or_create_shape_handle/2 should not return the same shape_handle for all columns and selected columns (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:127
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       handle = "95846100-1769512359187074"
     Showing 2 of 2 messages in the mailbox
     code: assert_receive {:snapshot, ^handle}
     mailbox:
       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "117685989-1769512359186753"}

       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512359187074"}
     stacktrace:
       test/electric/shape_cache_test.exs:1221: anonymous fn/1 in Electric.ShapeCacheTest.wait_snapshot/1
       (elixir 1.19.1) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
       test/electric/shape_cache_test.exs:1201: Electric.ShapeCacheTest.wait_shape_init/2
       test/electric/shape_cache_test.exs:142: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 returns existing shape_handle
Stack Traces | 0.418s run time
26) test get_or_create_shape_handle/2 returns existing shape_handle (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:95
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       handle = "95846100-1769512353848542"
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:snapshot, ^handle}
     mailbox:
       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512353848542"}
     stacktrace:
       test/electric/shape_cache_test.exs:1221: anonymous fn/1 in Electric.ShapeCacheTest.wait_snapshot/1
       (elixir 1.19.1) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
       test/electric/shape_cache_test.exs:1201: Electric.ShapeCacheTest.wait_shape_init/2
       test/electric/shape_cache_test.exs:99: (test)
Elixir.Electric.ShapeCacheTest::test has_shape?/2 works with slow snapshot generation
Stack Traces | 0.422s run time
15) test has_shape?/2 works with slow snapshot generation (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:633
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       handle = "95846100-1769512356080938"
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:snapshot, ^handle}
     mailbox:
       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512356080938"}
     stacktrace:
       test/electric/shape_cache_test.exs:1221: anonymous fn/1 in Electric.ShapeCacheTest.wait_snapshot/1
       (elixir 1.19.1) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
       test/electric/shape_cache_test.exs:1201: Electric.ShapeCacheTest.wait_shape_init/2
       test/electric/shape_cache_test.exs:643: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage transactions are buffered until snapshot xmin is known
Stack Traces | 0.424s run time
17) test transaction handling with real storage transactions are buffered until snapshot xmin is known (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:668
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       shape_handle = "27335419-1769512349752811"
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:snapshot, ^shape_handle}
     mailbox:
       pattern: {:snapshot, ^shape_handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "27335419-1769512349752811"}
     stacktrace:
       .../electric/shapes/consumer_test.exs:676: (test)
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 errors while streaming from database are sent to all callers
Stack Traces | 0.426s run time
28) test await_snapshot_start/4 errors while streaming from database are sent to all callers (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:735
     Assertion failed, no matching message after 400ms
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:stream_start, stream_pid}
     mailbox:
       pattern: {:stream_start, stream_pid}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512353333744"}
     stacktrace:
       test/electric/shape_cache_test.exs:798: (test)
Elixir.Electric.ShapeCacheTest::test list_shapes/1 lists the shape even if we don't know xmin
Stack Traces | 0.43s run time
21) test list_shapes/1 lists the shape even if we don't know xmin (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:549
     Assertion failed, no matching message after 400ms
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:waiting_point, ref, pid}
     mailbox:
       pattern: {:waiting_point, ref, pid}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512355132695"}
     stacktrace:
       test/electric/shape_cache_test.exs:569: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 creates a new shape_handle
Stack Traces | 0.431s run time
23) test get_or_create_shape_handle/2 creates a new shape_handle (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:89
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       handle = "95846100-1769512354500715"
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:snapshot, ^handle}
     mailbox:
       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512354500715"}
     stacktrace:
       test/electric/shape_cache_test.exs:1221: anonymous fn/1 in Electric.ShapeCacheTest.wait_snapshot/1
       (elixir 1.19.1) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
       test/electric/shape_cache_test.exs:1201: Electric.ShapeCacheTest.wait_shape_init/2
       test/electric/shape_cache_test.exs:92: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 shape initialization shape gets cleaned up if terminated unexpectedly
Stack Traces | 0.485s run time
8) test get_or_create_shape_handle/2 shape initialization shape gets cleaned up if terminated unexpectedly (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:270
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       consumer_ref = #Reference<0.707921848.1074003970.91423>
     Showing 2 of 2 messages in the mailbox
     code: assert_receive {:DOWN, ^consumer_ref, :process, _pid, :some_reason}
     mailbox:
       pattern: {:DOWN, ^consumer_ref, :process, _pid, :some_reason}
       value:   {:DOWN, #Reference<0.707921848.1074003970.91423>, :process, #PID<0.18807.0>, {:noproc, {PartitionSupervisor, :partitions, [{:via, Registry, {:"Electric.ProcessRegistry:Electric.ShapeCacheTest test get_or_create_shape_handle/2 shape initialization shape gets cleaned up if terminated unexpectedly", {Electric.Shapes.SnapshotterSupervisor, nil}}}]}}}

       pattern: {:DOWN, ^consumer_ref, :process, _pid, :some_reason}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "95846100-1769512358184096"}
     stacktrace:
       test/electric/shape_cache_test.exs:280: (test)
Elixir.Electric.ShapeCacheTest::test await_snapshot_start/4 should wait for consumer to come up
Stack Traces | 0.581s run time
9) test await_snapshot_start/4 should wait for consumer to come up (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:877
     match (=) failed
     code:  assert :started = Task.await(wait_task, start_consumer_delay)
     left:  :started
     right: {:error, :unknown}
     stacktrace:
       test/electric/shape_cache_test.exs:915: (test)
Elixir.Electric.ShapeCacheTest::test get_or_create_shape_handle/2 should not return the same shape_handle for different shapes despite hash collision
Stack Traces | 0.725s run time
33) test get_or_create_shape_handle/2 should not return the same shape_handle for different shapes despite hash collision (Electric.ShapeCacheTest)
     test/electric/shape_cache_test.exs:102
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       handle = "1234-1769512352413039"
     Showing 2 of 2 messages in the mailbox
     code: assert_receive {:snapshot, ^handle}
     mailbox:
       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "1234-1769512352413039"}

       pattern: {:snapshot, ^handle}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "1234-1769512352417328"}
     stacktrace:
       test/electric/shape_cache_test.exs:1221: anonymous fn/1 in Electric.ShapeCacheTest.wait_snapshot/1
       (elixir 1.19.1) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
       test/electric/shape_cache_test.exs:1201: Electric.ShapeCacheTest.wait_shape_init/2
       test/electric/shape_cache_test.exs:124: (test)
Elixir.Electric.Shapes.ConsumerTest::test transaction handling with real storage compaction is scheduled and invoked for a shape that has compaction enabled
Stack Traces | 0.803s run time
5) test transaction handling with real storage compaction is scheduled and invoked for a shape that has compaction enabled (Electric.Shapes.ConsumerTest)
     .../electric/shapes/consumer_test.exs:954
     Assertion failed, no matching message after 400ms
     The following variables were pinned:
       ref = #Reference<0.707921848.1074003969.29587>
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:consumer_did_invoke_compact, ^ref}
     mailbox:
       pattern: {:consumer_did_invoke_compact, ^ref}
       value:   {Electric.ShapeCache.ShapeCleaner, :cleanup, "27335419-1769512351236546"}
     stacktrace:
       .../electric/shapes/consumer_test.exs:969: (test)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@magnetised magnetised force-pushed the magnetised/sqlite-ets-cache branch 5 times, most recently from 6037b8a to 4168319 Compare January 22, 2026 10:49
@magnetised magnetised force-pushed the magnetised/speedup-shutdown branch from 2b93719 to f650b8a Compare January 22, 2026 13:45
@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Comment @coderabbitai help to get the list of available commands and usage tips.

@blacksmith-sh
Copy link
Contributor

blacksmith-sh bot commented Jan 22, 2026

Found 110 test failures on Blacksmith runners:

Failures

Test View Logs
Elixir.Electric.ShapeCacheTest/test after restart restores latest offset View Logs
Elixir.Electric.ShapeCacheTest/test after restart restores latest offset View Logs
Elixir.Electric.ShapeCacheTest/test after restart restores shape_handles View Logs
Elixir.Electric.ShapeCacheTest/test after restart restores shape_handles View Logs
Elixir.Electric.ShapeCacheTest/
test after restart restores shapes with subqueries and their materializers
View Logs
Elixir.Electric.ShapeCacheTest/
test after restart restores shapes with subqueries and their materializers
View Logs
Elixir.Electric.ShapeCacheTest/
test after restart restores shapes with subqueries and their materializers when backup
missing
View Logs
Elixir.Electric.ShapeCacheTest/
test after restart restores shapes with subqueries and their materializers when backup
missing
View Logs
Elixir.Electric.ShapeCacheTest/
test after restart waits until publication filters are restored
View Logs
Elixir.Electric.ShapeCacheTest/
test after restart waits until publication filters are restored
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 errors while streaming from database are sent to all callers
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 errors while streaming from database are sent to all callers
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 handles buffering multiple callers correctly
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 handles buffering multiple callers correctly
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 propagates error in snapshot creation to listeners
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 propagates error in snapshot creation to listeners
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 returns :started for snapshots that have started
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 returns :started for snapshots that have started
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 should stop awaiting if shape process dies unexpectedly
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 should stop awaiting if shape process dies unexpectedly
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 should wait for consumer to come up
View Logs
Elixir.Electric.ShapeCacheTest/test await_snapshot_start/
4 should wait for consumer to come up
View Logs
Elixir.Electric.ShapeCacheTest/test count_shapes/1 returns the correct count of shapes View Logs
Elixir.Electric.ShapeCacheTest/test count_shapes/1 returns the correct count of shapes View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db can create shape from partitioned table
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db can create shape from partitioned table
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db correctly propagates the error
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db correctly propagates the error
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db crashes when initial snapshot query fails to return data quickly enou
gh
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db crashes when initial snapshot query fails to return data quickly enou
gh
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db creates initial snapshot from DB data
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db creates initial snapshot from DB data
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db uses correct display settings when querying initial data
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 against real db uses correct display settings when querying initial data
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 creates a new shape_handle
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 creates a new shape_handle
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 returns existing shape_handle
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 returns existing shape_handle
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization creates initial snapshot if one doesn't exist
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization creates initial snapshot if one doesn't exist
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization shape gets cleaned up if terminated unexpectedly
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization shape gets cleaned up if terminated unexpectedly
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization triggers table prep and snapshot creation only once
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization triggers table prep and snapshot creation only once
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization triggers table prep and snapshot creation only once even with qu
eued requests
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 shape initialization triggers table prep and snapshot creation only once even with qu
eued requests
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 should not return the same shape_handle for all columns and selected columns
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 should not return the same shape_handle for all columns and selected columns
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 should not return the same shape_handle for different shapes despite hash collision
View Logs
Elixir.Electric.ShapeCacheTest/test get_or_create_shape_handle/
2 should not return the same shape_handle for different shapes despite hash collision
View Logs
Elixir.Electric.ShapeCacheTest/test has_shape?/2 returns true for known shape handle View Logs
Elixir.Electric.ShapeCacheTest/test has_shape?/2 returns true for known shape handle View Logs
Elixir.Electric.ShapeCacheTest/test has_shape?/2 works with slow snapshot generation View Logs
Elixir.Electric.ShapeCacheTest/test has_shape?/2 works with slow snapshot generation View Logs
Elixir.Electric.ShapeCacheTest/test list_shapes/
1 lists the shape as active once there is a snapshot
View Logs
Elixir.Electric.ShapeCacheTest/test list_shapes/
1 lists the shape as active once there is a snapshot
View Logs
Elixir.Electric.ShapeCacheTest/test list_shapes/
1 lists the shape even if we don't know xmin
View Logs
Elixir.Electric.ShapeCacheTest/test list_shapes/
1 lists the shape even if we don't know xmin
View Logs
Elixir.Electric.ShapeCacheTest/test start_consumer_for_handle/
2 starts a consumer plus dependencies
View Logs
Elixir.Electric.ShapeCacheTest/test start_consumer_for_handle/
2 starts a consumer plus dependencies
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shape/
2 cleans up shape data and rotates the shape handle
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shape/
2 cleans up shape data and rotates the shape handle
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shape_async/
2 cleans up shape data and rotates the shape handle
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shape_async/
2 cleans up shape data and rotates the shape handle
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shapes_for_relations/
2 cleans up shape data for relevant shapes
View Logs
Elixir.Electric.ShapeCleanerTest/test remove_shapes_for_relations/
2 cleans up shape data for relevant shapes
View Logs
Elixir.Electric.Shapes.ConsumerTest/test event handling appends to log when xid >= xmin View Logs
Elixir.Electric.Shapes.ConsumerTest/test event handling appends to log when xid >= xmin View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling cleans shapes affected by a relation change
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling cleans shapes affected by a relation change
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling cleans shapes affected by a relation rename
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling cleans shapes affected by a relation rename
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling consumer crashing stops affected consumer
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling consumer crashing stops affected consumer
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling correctly writes only relevant changes to multiple shape logs
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling correctly writes only relevant changes to multiple shape logs
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling does not clean shapes if relation didn't change
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling does not clean shapes if relation didn't change
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling doesn't append to log when change is irrelevant for active shapes
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling doesn't append to log when change is irrelevant for active shapes
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling handles truncate when shape has a where clause
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling handles truncate when shape has a where clause
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling handles truncate without appending to log
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling handles truncate without appending to log
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling notifies listeners of new changes
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling notifies listeners of new changes
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling notifies live listeners when invalidated
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test event handling notifies live listeners when invalidated
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage compaction is scheduled and invoked for a s
hape that has compaction enabled
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage compaction is scheduled and invoked for a s
hape that has compaction enabled
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage ConsumerRegistry.enable_suspend should susp
end hibernated consumers
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage ConsumerRegistry.enable_suspend should susp
end hibernated consumers
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage duplicate transactions storage is idempoten
t
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage duplicate transactions storage is idempoten
t
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage restarting a consumer doesn't lower the las
t known offset when only snapshot is present
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage restarting a consumer doesn't lower the las
t known offset when only snapshot is present
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should correctly normalize a flush boundary
to txn
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should correctly normalize a flush boundary
to txn
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should hibernate not suspend if has depende
ncies
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should hibernate not suspend if has depende
ncies
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should notify txns skipped because of xmin/
xip as flushed
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should notify txns skipped because of xmin/
xip as flushed
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should terminate after :hibernate_after ms
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage should terminate after :hibernate_after ms
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage terminating the consumers cleans up its ent
ry from Storage ETS
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage terminating the consumers cleans up its ent
ry from Storage ETS
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage transactions are buffered until snapshot xm
in is known
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage transactions are buffered until snapshot xm
in is known
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage UPDATE during pending move-in is converted
to INSERT and query result skips duplicate key
View Logs
Elixir.Electric.Shapes.ConsumerTest/
test transaction handling with real storage UPDATE during pending move-in is converted
to INSERT and query result skips duplicate key
View Logs

Fix in Cursor

# need to call `super()` to obtain the original DynamicSupervisor child_spec() to pass as an option to
# PartitionSupervisor.
PartitionSupervisor.child_spec(
child_spec: Supervisor.child_spec(super(opts), shutdown: :brutal_kill),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we not specify this shutdown policy on the snapshotter genserver?

Base automatically changed from magnetised/sqlite-ets-cache to main January 26, 2026 16:23
@magnetised magnetised force-pushed the magnetised/speedup-shutdown branch from 31df264 to 0d4debb Compare January 27, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants