Add replica for global region support

This commit is contained in:
Chris McCord 2022-01-27 20:42:26 -05:00
parent 5f6911ce98
commit 31c69acd10
8 changed files with 58 additions and 15 deletions

View file

@ -8,6 +8,7 @@
import Config import Config
config :live_beats, config :live_beats,
replica: LiveBeats.ReplicaRepo,
ecto_repos: [LiveBeats.Repo] ecto_repos: [LiveBeats.Repo]
# Configures the endpoint # Configures the endpoint

View file

@ -20,6 +20,16 @@ config :live_beats, LiveBeats.Repo,
show_sensitive_data_on_connection_error: true, show_sensitive_data_on_connection_error: true,
pool_size: 10 pool_size: 10
# Configure your replica database
config :live_beats, LiveBeats.ReplicaRepo,
username: "postgres",
password: "postgres",
database: "live_beats_dev",
hostname: "localhost",
show_sensitive_data_on_connection_error: true,
pool_size: 10,
priv: "priv/repo"
# For development, we disable any cache and enable # For development, we disable any cache and enable
# debugging and code reloading. # debugging and code reloading.
# #

View file

@ -19,6 +19,9 @@ if config_env() == :prod do
For example: ecto://USER:PASS@HOST/DATABASE For example: ecto://USER:PASS@HOST/DATABASE
""" """
replica_database_url =
System.get_env("REPLICA_DATABASE_URL") || database_url
host = System.get_env("PHX_HOST") || "example.com" host = System.get_env("PHX_HOST") || "example.com"
ecto_ipv6? = System.get_env("ECTO_IPV6") == "true" ecto_ipv6? = System.get_env("ECTO_IPV6") == "true"
@ -32,6 +35,13 @@ if config_env() == :prod do
url: database_url, url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10") pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
config :live_beats, LiveBeats.ReplicaRepo,
# ssl: true,
priv: "priv/repo",
socket_options: if(ecto_ipv6?, do: [:inet6], else: []),
url: replica_database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
secret_key_base = secret_key_base =
System.get_env("SECRET_KEY_BASE") || System.get_env("SECRET_KEY_BASE") ||
raise """ raise """

View file

@ -1,5 +1,8 @@
import Config import Config
config :live_beats,
replica: LiveBeats.Repo
config :live_beats, :files, config :live_beats, :files,
uploads_dir: Path.expand("../tmp/test-uploads", __DIR__), uploads_dir: Path.expand("../tmp/test-uploads", __DIR__),
host: [scheme: "http", host: "localhost", port: 4000], host: [scheme: "http", host: "localhost", port: 4000],
@ -18,6 +21,16 @@ config :live_beats, LiveBeats.Repo,
pool: Ecto.Adapters.SQL.Sandbox, pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 10 pool_size: 10
config :live_beats, LiveBeats.ReplicaRepo,
username: "postgres",
password: "postgres",
database: "live_beats_test#{System.get_env("MIX_TEST_PARTITION")}",
hostname: "localhost",
show_sensitive_data_on_connection_error: true,
pool_size: 10,
priv: "priv/repo"
# We don't run a server during test. If one is required, # We don't run a server during test. If one is required,
# you can enable the server option below. # you can enable the server option below.
config :live_beats, LiveBeatsWeb.Endpoint, config :live_beats, LiveBeatsWeb.Endpoint,

View file

@ -18,15 +18,15 @@ defmodule LiveBeats.Accounts do
defp topic(user_id), do: "user:#{user_id}" defp topic(user_id), do: "user:#{user_id}"
def list_users(opts) do def list_users(opts) do
Repo.all(from u in User, limit: ^Keyword.fetch!(opts, :limit)) Repo.replica().all(from u in User, limit: ^Keyword.fetch!(opts, :limit))
end end
def get_users_map(user_ids) when is_list(user_ids) do def get_users_map(user_ids) when is_list(user_ids) do
Repo.all(from u in User, where: u.id in ^user_ids, select: {u.id, u}) Repo.replica().all(from u in User, where: u.id in ^user_ids, select: {u.id, u})
end end
def lists_users_by_active_profile(id, opts) do def lists_users_by_active_profile(id, opts) do
Repo.all( Repo.replica().all(
from u in User, where: u.active_profile_user_id == ^id, limit: ^Keyword.fetch!(opts, :limit) from u in User, where: u.active_profile_user_id == ^id, limit: ^Keyword.fetch!(opts, :limit)
) )
end end
@ -84,11 +84,11 @@ defmodule LiveBeats.Accounts do
** (Ecto.NoResultsError) ** (Ecto.NoResultsError)
""" """
def get_user!(id), do: Repo.get!(User, id) def get_user!(id), do: Repo.replica().get!(User, id)
def get_user(id), do: Repo.get(User, id) def get_user(id), do: Repo.replica().get(User, id)
def get_user_by!(fields), do: Repo.get_by!(User, fields) def get_user_by!(fields), do: Repo.replica().get_by!(User, fields)
def update_active_profile(%User{active_profile_user_id: same_id} = current_user, same_id) do def update_active_profile(%User{active_profile_user_id: same_id} = current_user, same_id) do
current_user current_user

View file

@ -15,6 +15,7 @@ defmodule LiveBeats.Application do
{Task.Supervisor, name: LiveBeats.TaskSupervisor}, {Task.Supervisor, name: LiveBeats.TaskSupervisor},
# Start the Ecto repository # Start the Ecto repository
LiveBeats.Repo, LiveBeats.Repo,
LiveBeats.ReplicaRepo,
# Start the Telemetry supervisor # Start the Telemetry supervisor
LiveBeatsWeb.Telemetry, LiveBeatsWeb.Telemetry,
# Start the PubSub system # Start the PubSub system

View file

@ -228,13 +228,13 @@ defmodule LiveBeats.MediaLibrary do
end end
def list_genres do def list_genres do
Repo.all(Genre, order_by: [asc: :title]) Repo.replica().all(Genre, order_by: [asc: :title])
end end
def list_profile_songs(%Profile{} = profile, limit \\ 100) do def list_profile_songs(%Profile{} = profile, limit \\ 100) do
from(s in Song, where: s.user_id == ^profile.user_id, limit: ^limit) from(s in Song, where: s.user_id == ^profile.user_id, limit: ^limit)
|> order_by_playlist(:asc) |> order_by_playlist(:asc)
|> Repo.all() |> Repo.replica().all()
end end
def list_active_profiles(opts) do def list_active_profiles(opts) do
@ -246,12 +246,12 @@ defmodule LiveBeats.MediaLibrary do
order_by: [desc: s.updated_at], order_by: [desc: s.updated_at],
select: struct(u, [:id, :username, :profile_tagline, :avatar_url, :external_homepage_url]) select: struct(u, [:id, :username, :profile_tagline, :avatar_url, :external_homepage_url])
) )
|> Repo.all() |> Repo.replica().all()
|> Enum.map(&get_profile!/1) |> Enum.map(&get_profile!/1)
end end
def get_current_active_song(%Profile{user_id: user_id}) do def get_current_active_song(%Profile{user_id: user_id}) do
Repo.one(from s in Song, where: s.user_id == ^user_id and s.status in [:playing, :paused]) Repo.replica().one(from s in Song, where: s.user_id == ^user_id and s.status in [:playing, :paused])
end end
def get_profile!(%Accounts.User{} = user) do def get_profile!(%Accounts.User{} = user) do
@ -286,7 +286,7 @@ defmodule LiveBeats.MediaLibrary do
end end
end end
def get_song!(id), do: Repo.get!(Song, id) def get_song!(id), do: Repo.replica().get!(Song, id)
def get_first_song(%Profile{user_id: user_id}) do def get_first_song(%Profile{user_id: user_id}) do
from(s in Song, from(s in Song,
@ -294,7 +294,7 @@ defmodule LiveBeats.MediaLibrary do
limit: 1 limit: 1
) )
|> order_by_playlist(:asc) |> order_by_playlist(:asc)
|> Repo.one() |> Repo.replica().one()
end end
def get_last_song(%Profile{user_id: user_id}) do def get_last_song(%Profile{user_id: user_id}) do
@ -303,7 +303,7 @@ defmodule LiveBeats.MediaLibrary do
limit: 1 limit: 1
) )
|> order_by_playlist(:desc) |> order_by_playlist(:desc)
|> Repo.one() |> Repo.replica().one()
end end
def get_next_song(%Song{} = song, %Profile{} = profile) do def get_next_song(%Song{} = song, %Profile{} = profile) do
@ -313,7 +313,7 @@ defmodule LiveBeats.MediaLibrary do
limit: 1 limit: 1
) )
|> order_by_playlist(:asc) |> order_by_playlist(:asc)
|> Repo.one() |> Repo.replica().one()
next || get_first_song(profile) next || get_first_song(profile)
end end
@ -326,7 +326,7 @@ defmodule LiveBeats.MediaLibrary do
limit: 1 limit: 1
) )
|> order_by_playlist(:desc) |> order_by_playlist(:desc)
|> Repo.one() |> Repo.replica().one()
prev || get_last_song(profile) prev || get_last_song(profile)
end end

View file

@ -2,4 +2,12 @@ defmodule LiveBeats.Repo do
use Ecto.Repo, use Ecto.Repo,
otp_app: :live_beats, otp_app: :live_beats,
adapter: Ecto.Adapters.Postgres adapter: Ecto.Adapters.Postgres
def replica, do: LiveBeats.config([:replica])
end
defmodule LiveBeats.ReplicaRepo do
use Ecto.Repo,
otp_app: :live_beats,
adapter: Ecto.Adapters.Postgres
end end