Packages
electric
1.7.4
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.16
1.4.16-beta-1
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
retired
1.1.5
retired
1.1.4
retired
1.1.3
retired
1.1.2
1.1.1
1.1.0
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.15
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-beta.23
1.0.0-beta.22
1.0.0-beta.20
1.0.0-beta.19
1.0.0-beta.18
1.0.0-beta.17
1.0.0-beta.16
1.0.0-beta.15
1.0.0-beta.14
1.0.0-beta.13
1.0.0-beta.12
1.0.0-beta.11
1.0.0-beta.10
1.0.0-beta.9
1.0.0-beta.8
1.0.0-beta.7
1.0.0-beta.6
1.0.0-beta.5
1.0.0-beta.4
1.0.0-beta.3
1.0.0-beta.2
1.0.0-beta.1
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.5.2
0.4.4
Postgres sync engine. Sync little subsets of your Postgres data into local apps and services.
Current section
Files
Jump to
Current section
Files
lib/electric/shape_cache/shape_status_owner.ex
defmodule Electric.ShapeCache.ShapeStatusOwner do
@moduledoc """
Owns the ETS table and the ShapeStatus state.
This process creates the ETS table for shapes and initializes
`Electric.ShapeCache.ShapeStatus` early in the supervision tree so that
dependent processes (e.g., shape consumers) can use a single, shared
ShapeStatus instance regardless of their own supervisor start order.
Initialization is done asynchronously via `handle_continue` to avoid
blocking the supervision tree startup on potentially slow SQLite reads.
"""
use GenServer
alias Electric.ShapeCache.ShapeStatus
require Logger
@schema NimbleOptions.new!(stack_id: [type: :string, required: true])
def name(stack_id) do
Electric.ProcessRegistry.name(stack_id, __MODULE__)
end
@doc """
Refresh shape metadata from SQLite after lock acquisition.
Uses an infinite timeout because on laggy storage with an incorrectly
shut-down database this can take a long time.
"""
def refresh(stack_id) do
GenServer.call(name(stack_id), :refresh, :infinity)
end
def start_link(opts) do
with {:ok, opts} <- NimbleOptions.validate(opts, @schema) do
opts = Map.new(opts)
GenServer.start_link(__MODULE__, opts, name: name(opts.stack_id))
end
end
@impl true
def init(config) do
stack_id = config.stack_id
Process.set_label({:shape_status_owner, stack_id})
Logger.metadata(stack_id: stack_id)
Electric.Telemetry.Sentry.set_tags_context(stack_id: stack_id)
:ok = Electric.LsnTracker.initialize(stack_id)
{:ok, %{stack_id: stack_id}, {:continue, :initialize}}
end
@impl true
def handle_continue(:initialize, state) do
# Initialize shape metadata from SQLite so we can serve shapes in
# read-only mode before the advisory lock is acquired
:ok = ShapeStatus.initialize(state.stack_id)
# Signal that shape metadata is loaded and shapes can be served read-only
Electric.StatusMonitor.mark_shape_metadata_ready(state.stack_id, self())
Logger.notice("Shape metadata initialized, entering read-only mode")
{:noreply, state, :hibernate}
end
@impl true
def handle_call(:refresh, _from, state) do
:ok = ShapeStatus.refresh(state.stack_id)
{:reply, :ok, state, :hibernate}
end
end