Packages
electric
1.7.7
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/shape_db/pool_registry.ex
defmodule Electric.ShapeCache.ShapeStatus.ShapeDb.PoolRegistry do
@moduledoc """
Manages pool registration for a stack. Contains the `exclusive_mode` logic,
so that when enabled, the same write connection is returned for reads and
writes.
In `exclusive_mode` only the writer pool is started by the supervisor.
"""
use GenServer
import Electric, only: [is_stack_id: 1]
def start_link(args) do
GenServer.start_link(__MODULE__, args)
end
@doc """
Used by pool processes for registration. The `exclusive?` boolean is passed
onto the `register_name/2` call and determines whether the connection is
registered for both reads and writes in `exclusive_mode`.
"""
def pool_name(stack_id, role, exclusive?)
when is_stack_id(stack_id) and role in [:read, :write] do
{:via, __MODULE__, {stack_id, role, exclusive?}}
end
@doc """
Used by ShapeDb to retrieve a pool.
"""
def pool_name(stack_id, role) when is_stack_id(stack_id) and role in [:read, :write] do
{:via, __MODULE__, {stack_id, role}}
end
# GenServer name registration callback
def register_name({stack_id, role, exclusive?}, pid) when is_stack_id(stack_id) do
keys = pool_keys(role, exclusive?, pid)
if :ets.insert_new(ets_table(stack_id), keys), do: :yes, else: :no
end
# GenServer name registration callback
def unregister_name({stack_id, role, exclusive?}) do
table = ets_table(stack_id)
pool_keys(role, exclusive?)
|> Enum.each(&:ets.delete(table, &1))
end
# GenServer name registration callback
def whereis_name({stack_id, role}) do
:ets.lookup_element(ets_table(stack_id), role, 2, nil) || :undefined
end
# GenServer name registration callback
def whereis_name({stack_id, :write, true}) do
:ets.lookup_element(ets_table(stack_id), :write, 2, nil) || :undefined
end
def whereis_name({stack_id, role, false}) do
:ets.lookup_element(ets_table(stack_id), role, 2, nil) || :undefined
end
defp pool_keys(:write, true, pid) do
[{:read, pid}, {:write, pid}]
end
defp pool_keys(role, false, pid) do
[{role, pid}]
end
# used by unregister_name/1
defp pool_keys(:write, true) do
[:read, :write]
end
defp pool_keys(role, false) do
[role]
end
@impl GenServer
def init(args) do
stack_id = Keyword.fetch!(args, :stack_id)
Process.set_label({:shape_db_pool_registry, stack_id})
Logger.metadata(stack_id: stack_id)
table =
:ets.new(ets_table(stack_id), [
:public,
:named_table,
read_concurrency: true,
write_concurrency: :auto
])
{:ok, %{table: table, stack_id: stack_id}}
end
defp ets_table(stack_id),
do: :"Electric.ShapeCache.ShapeStatus.ShapeDb.PoolRegistry:#{stack_id}"
end