Packages
electric
1.0.0-beta.11
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/application.ex
defmodule Electric.Application do
use Application
require Config
@doc """
This callback starts the entire application, but is configured to run only when
this app is started on it's own, not as a library. As such, this should be the only
place that actually reads from `Application.get_env/2`, because it's the only context
where the `config/runtime.exs` is executed.
"""
@impl true
def start(_type, _args) do
:erlang.system_flag(:backtrace_depth, 50)
Electric.Config.ensure_instance_id()
Electric.Telemetry.Sentry.add_logger_handler()
# We have "instance id" identifier as the node ID, however that's generated every runtime,
# so isn't stable across restarts. Our storages however scope themselves based on this stack ID
# so we're just hardcoding it here.
stack_id = Electric.Config.get_env(:provided_database_id)
storage = Electric.Config.get_env(:storage)
router_opts =
[
long_poll_timeout: 20_000,
max_age: Electric.Config.get_env(:cache_max_age),
stale_age: Electric.Config.get_env(:cache_stale_age),
allow_shape_deletion: Electric.Config.get_env(:allow_shape_deletion?)
] ++
Electric.StackSupervisor.build_shared_opts(
stack_id: stack_id,
stack_events_registry: Registry.StackEvents,
storage: storage
)
{kv_module, kv_fun, kv_params} =
Electric.Config.get_env(:persistent_kv)
persistent_kv = apply(kv_module, kv_fun, [kv_params])
replication_stream_id = Electric.Config.get_env(:replication_stream_id)
publication_name = "electric_publication_#{replication_stream_id}"
slot_name = "electric_slot_#{replication_stream_id}"
# The root application supervisor starts the core global processes, including the HTTP
# server and the database connection manager. The latter is responsible for establishing
# all needed connections to the database (acquiring the exclusive access lock, opening a
# replication connection, starting a connection pool).
#
# Once there is a DB connection pool running, Connection.Manager will start the singleton
# `Electric.Replication.Supervisor` which is responsible for starting the shape log collector
# and individual shape consumer process trees.
#
# See the moduledoc in `Electric.Connection.Supervisor` for more info.
children =
Enum.concat([
[
{Registry, name: Registry.StackEvents, keys: :duplicate},
{
Electric.StackSupervisor,
stack_id: stack_id,
stack_events_registry: Registry.StackEvents,
connection_opts: Electric.Config.fetch_env!(:connection_opts),
persistent_kv: persistent_kv,
replication_opts: [
publication_name: publication_name,
slot_name: slot_name,
slot_temporary?: Electric.Config.get_env(:replication_slot_temporary?)
],
pool_opts: [pool_size: Electric.Config.get_env(:db_pool_size)],
storage: storage,
chunk_bytes_threshold: Electric.Config.get_env(:chunk_bytes_threshold)
},
{Electric.Telemetry, stack_id: stack_id, storage: storage},
{Bandit,
plug: {Electric.Plug.Router, router_opts},
port: Electric.Config.get_env(:service_port),
thousand_island_options: http_listener_options()}
],
prometheus_endpoint(Electric.Config.get_env(:prometheus_port))
])
Supervisor.start_link(children, strategy: :one_for_one, name: Electric.Supervisor)
end
defp prometheus_endpoint(nil), do: []
defp prometheus_endpoint(port) do
[
{
Bandit,
plug: {Electric.Plug.UtilityRouter, []},
port: port,
thousand_island_options: http_listener_options()
}
]
end
defp http_listener_options do
if Electric.Config.get_env(:listen_on_ipv6?) do
[transport_options: [:inet6]]
else
[]
end
end
end