From f60b8ba02a466368a8b7ca33b30f7c604f1a3541 Mon Sep 17 00:00:00 2001 From: Steffen Beyer Date: Wed, 18 Mar 2026 18:26:54 +0100 Subject: [PATCH] Add memory-backed benchmark profile --- README.md | 16 ++++- config/config.exs | 3 + config/runtime.exs | 102 ++++++++++++++++++++++++---- lib/parrhesia/postgres_repos.ex | 50 +++++++++++--- lib/parrhesia/storage/supervisor.ex | 18 +++-- lib/parrhesia/tasks/supervisor.ex | 10 ++- scripts/run_bench_compare.sh | 37 +++++++--- scripts/run_e2e_suite.sh | 22 +++--- scripts/run_nostr_bench.sh | 56 ++++++++++++++- test/parrhesia/storage_test.exs | 20 ++++++ 10 files changed, 278 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 80ffa3f..328f48c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,12 @@ Parrhesia Logo -Parrhesia is a Nostr relay server written in Elixir/OTP with PostgreSQL storage. +Parrhesia is a Nostr relay server written in Elixir/OTP. + +Supported storage backends: + +- PostgreSQL, which is the primary and production-oriented backend +- in-memory storage, which is useful for tests, local experiments, and benchmarks **ALPHA CONDITION – BREAKING CHANGES MIGHT HAPPEN!** @@ -118,6 +123,9 @@ Before a Nostr client can publish its first event successfully, make sure these 1. PostgreSQL is reachable from Parrhesia. Set `DATABASE_URL` and create/migrate the database with `Parrhesia.Release.migrate()` or `mix ecto.migrate`. + PostgreSQL is the supported production datastore. The in-memory backend is intended for + non-persistent runs such as tests and benchmarks. + 2. Parrhesia listeners are configured for your deployment. The default config exposes a `public` listener on plain HTTP port `4413`, and a reverse proxy can terminate TLS and forward WebSocket traffic to `/relay`. Additional listeners can be defined in `config/*.exs`. @@ -153,6 +161,8 @@ For runtime overrides, use the `PARRHESIA_...` prefix: - `PARRHESIA_PUBLIC_MAX_CONNECTIONS` - `PARRHESIA_MODERATION_CACHE_ENABLED` - `PARRHESIA_ENABLE_EXPIRATION_WORKER` +- `PARRHESIA_ENABLE_PARTITION_RETENTION_WORKER` +- `PARRHESIA_STORAGE_BACKEND` - `PARRHESIA_LIMITS_*` - `PARRHESIA_POLICIES_*` - `PARRHESIA_METRICS_*` @@ -496,7 +506,9 @@ Notes: ## Benchmark -The benchmark compares Parrhesia against [`strfry`](https://github.com/hoytech/strfry) and [`nostr-rs-relay`](https://sr.ht/~gheartsfield/nostr-rs-relay/) using [`nostr-bench`](https://github.com/rnostr/nostr-bench). +The benchmark compares two Parrhesia profiles, one backed by PostgreSQL and one backed by the in-memory adapter, against [`strfry`](https://github.com/hoytech/strfry) and [`nostr-rs-relay`](https://sr.ht/~gheartsfield/nostr-rs-relay/) using [`nostr-bench`](https://github.com/rnostr/nostr-bench). Benchmark runs also lift Parrhesia's relay-side limits by default so the benchmark client, not server guardrails, is the main bottleneck. + +`mix bench` is a sequential mixed-workload benchmark, not an isolated per-endpoint microbenchmark. Each relay instance runs `connect`, then `echo`, then `event`, then `req` against the same live process, so later phases measure against state and load created by earlier phases. Run it with: diff --git a/config/config.exs b/config/config.exs index 3c82952..6aa99df 100644 --- a/config/config.exs +++ b/config/config.exs @@ -18,6 +18,7 @@ config :parrhesia, separate_read_pool?: config_env() != :test ], moderation_cache_enabled: true, + enable_partition_retention_worker: true, relay_url: "ws://localhost:4413/relay", nip43: [ enabled: true, @@ -127,7 +128,9 @@ config :parrhesia, marmot_push_notifications: false ], storage: [ + backend: :postgres, events: Parrhesia.Storage.Adapters.Postgres.Events, + acl: Parrhesia.Storage.Adapters.Postgres.ACL, moderation: Parrhesia.Storage.Adapters.Postgres.Moderation, groups: Parrhesia.Storage.Adapters.Postgres.Groups, admin: Parrhesia.Storage.Adapters.Postgres.Admin diff --git a/config/runtime.exs b/config/runtime.exs index 63372ef..f099c15 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -35,6 +35,20 @@ bool_env = fn name, default -> end end +storage_backend_env = fn name, default -> + case System.get_env(name) do + nil -> + default + + value -> + case String.downcase(String.trim(value)) do + "postgres" -> :postgres + "memory" -> :memory + _other -> raise "environment variable #{name} must be one of: postgres, memory" + end + end +end + csv_env = fn name, default -> case System.get_env(name) do nil -> @@ -125,14 +139,12 @@ ipv4_env = fn name, default -> end if config_env() == :prod do - database_url = - System.get_env("DATABASE_URL") || - raise "environment variable DATABASE_URL is missing. Example: ecto://USER:PASS@HOST/DATABASE" - repo_defaults = Application.get_env(:parrhesia, Parrhesia.Repo, []) read_repo_defaults = Application.get_env(:parrhesia, Parrhesia.ReadRepo, []) relay_url_default = Application.get_env(:parrhesia, :relay_url) metadata_defaults = Application.get_env(:parrhesia, :metadata, []) + database_defaults = Application.get_env(:parrhesia, :database, []) + storage_defaults = Application.get_env(:parrhesia, :storage, []) moderation_cache_enabled_default = Application.get_env(:parrhesia, :moderation_cache_enabled, true) @@ -140,6 +152,9 @@ if config_env() == :prod do enable_expiration_worker_default = Application.get_env(:parrhesia, :enable_expiration_worker, true) + enable_partition_retention_worker_default = + Application.get_env(:parrhesia, :enable_partition_retention_worker, true) + limits_defaults = Application.get_env(:parrhesia, :limits, []) policies_defaults = Application.get_env(:parrhesia, :policies, []) listeners_defaults = Application.get_env(:parrhesia, :listeners, %{}) @@ -156,6 +171,29 @@ if config_env() == :prod do default_read_queue_interval = Keyword.get(read_repo_defaults, :queue_interval, default_queue_interval) + default_storage_backend = + storage_defaults + |> Keyword.get(:backend, :postgres) + |> case do + :postgres -> :postgres + :memory -> :memory + other -> raise "unsupported storage backend default: #{inspect(other)}" + end + + storage_backend = storage_backend_env.("PARRHESIA_STORAGE_BACKEND", default_storage_backend) + postgres_backend? = storage_backend == :postgres + + separate_read_pool? = + postgres_backend? and Keyword.get(database_defaults, :separate_read_pool?, true) + + database_url = + if postgres_backend? do + System.get_env("DATABASE_URL") || + raise "environment variable DATABASE_URL is missing. Example: ecto://USER:PASS@HOST/DATABASE" + else + nil + end + pool_size = int_env.("POOL_SIZE", default_pool_size) queue_target = int_env.("DB_QUEUE_TARGET_MS", default_queue_target) queue_interval = int_env.("DB_QUEUE_INTERVAL_MS", default_queue_interval) @@ -633,19 +671,47 @@ if config_env() == :prod do ) ] - config :parrhesia, Parrhesia.Repo, - url: database_url, - pool_size: pool_size, - queue_target: queue_target, - queue_interval: queue_interval + storage = + case storage_backend do + :postgres -> + [ + backend: :postgres, + events: Parrhesia.Storage.Adapters.Postgres.Events, + acl: Parrhesia.Storage.Adapters.Postgres.ACL, + moderation: Parrhesia.Storage.Adapters.Postgres.Moderation, + groups: Parrhesia.Storage.Adapters.Postgres.Groups, + admin: Parrhesia.Storage.Adapters.Postgres.Admin + ] - config :parrhesia, Parrhesia.ReadRepo, - url: database_url, - pool_size: read_pool_size, - queue_target: read_queue_target, - queue_interval: read_queue_interval + :memory -> + [ + backend: :memory, + events: Parrhesia.Storage.Adapters.Memory.Events, + acl: Parrhesia.Storage.Adapters.Memory.ACL, + moderation: Parrhesia.Storage.Adapters.Memory.Moderation, + groups: Parrhesia.Storage.Adapters.Memory.Groups, + admin: Parrhesia.Storage.Adapters.Memory.Admin + ] + end + + if postgres_backend? do + config :parrhesia, Parrhesia.Repo, + url: database_url, + pool_size: pool_size, + queue_target: queue_target, + queue_interval: queue_interval + + config :parrhesia, Parrhesia.ReadRepo, + url: database_url, + pool_size: read_pool_size, + queue_target: read_queue_target, + queue_interval: read_queue_interval + end config :parrhesia, + database: [ + separate_read_pool?: separate_read_pool? + ], relay_url: string_env.("PARRHESIA_RELAY_URL", relay_url_default), metadata: [ name: Keyword.get(metadata_defaults, :name, "Parrhesia"), @@ -679,11 +745,17 @@ if config_env() == :prod do bool_env.("PARRHESIA_MODERATION_CACHE_ENABLED", moderation_cache_enabled_default), enable_expiration_worker: bool_env.("PARRHESIA_ENABLE_EXPIRATION_WORKER", enable_expiration_worker_default), + enable_partition_retention_worker: + bool_env.( + "PARRHESIA_ENABLE_PARTITION_RETENTION_WORKER", + enable_partition_retention_worker_default + ), listeners: listeners, limits: limits, policies: policies, retention: retention, - features: features + features: features, + storage: storage case System.get_env("PARRHESIA_EXTRA_CONFIG") do nil -> :ok diff --git a/lib/parrhesia/postgres_repos.ex b/lib/parrhesia/postgres_repos.ex index 5eaed18..b0bdf82 100644 --- a/lib/parrhesia/postgres_repos.ex +++ b/lib/parrhesia/postgres_repos.ex @@ -19,27 +19,55 @@ defmodule Parrhesia.PostgresRepos do @spec started_repos() :: [module()] def started_repos do - if separate_read_pool_enabled?() do - [Repo, ReadRepo] - else - [Repo] + cond do + not postgres_enabled?() -> + [] + + separate_read_pool_enabled?() -> + [Repo, ReadRepo] + + true -> + [Repo] + end + end + + @spec postgres_enabled?() :: boolean() + def postgres_enabled? do + case Process.whereis(Config) do + pid when is_pid(pid) -> + Config.get([:storage, :backend], storage_backend_default()) == :postgres + + nil -> + storage_backend_default() == :postgres end end @spec separate_read_pool_enabled?() :: boolean() def separate_read_pool_enabled? do - case Process.whereis(Config) do - pid when is_pid(pid) -> - Config.get([:database, :separate_read_pool?], application_default()) + case {postgres_enabled?(), Process.whereis(Config)} do + {false, _pid} -> + false - nil -> - application_default() + {true, pid} when is_pid(pid) -> + Config.get( + [:database, :separate_read_pool?], + application_default(:separate_read_pool?, false) + ) + + {true, nil} -> + application_default(:separate_read_pool?, false) end end - defp application_default do + defp application_default(key, default) do :parrhesia |> Application.get_env(:database, []) - |> Keyword.get(:separate_read_pool?, false) + |> Keyword.get(key, default) + end + + defp storage_backend_default do + :parrhesia + |> Application.get_env(:storage, []) + |> Keyword.get(:backend, :postgres) end end diff --git a/lib/parrhesia/storage/supervisor.ex b/lib/parrhesia/storage/supervisor.ex index 4b58c43..3e73332 100644 --- a/lib/parrhesia/storage/supervisor.ex +++ b/lib/parrhesia/storage/supervisor.ex @@ -13,12 +13,20 @@ defmodule Parrhesia.Storage.Supervisor do @impl true def init(_init_arg) do - children = - [ - {Parrhesia.Storage.Adapters.Postgres.ModerationCache, - name: Parrhesia.Storage.Adapters.Postgres.ModerationCache} - ] ++ PostgresRepos.started_repos() + children = moderation_cache_children() ++ PostgresRepos.started_repos() Supervisor.init(children, strategy: :one_for_one) end + + defp moderation_cache_children do + if PostgresRepos.postgres_enabled?() and + Application.get_env(:parrhesia, :moderation_cache_enabled, true) do + [ + {Parrhesia.Storage.Adapters.Postgres.ModerationCache, + name: Parrhesia.Storage.Adapters.Postgres.ModerationCache} + ] + else + [] + end + end end diff --git a/lib/parrhesia/tasks/supervisor.ex b/lib/parrhesia/tasks/supervisor.ex index eabeaa5..b8f54af 100644 --- a/lib/parrhesia/tasks/supervisor.ex +++ b/lib/parrhesia/tasks/supervisor.ex @@ -25,9 +25,13 @@ defmodule Parrhesia.Tasks.Supervisor do end defp partition_retention_children do - [ - {Parrhesia.Tasks.PartitionRetentionWorker, name: Parrhesia.Tasks.PartitionRetentionWorker} - ] + if Application.get_env(:parrhesia, :enable_partition_retention_worker, true) do + [ + {Parrhesia.Tasks.PartitionRetentionWorker, name: Parrhesia.Tasks.PartitionRetentionWorker} + ] + else + [] + end end defp nip66_children do diff --git a/scripts/run_bench_compare.sh b/scripts/run_bench_compare.sh index 93bc150..177f34a 100755 --- a/scripts/run_bench_compare.sh +++ b/scripts/run_bench_compare.sh @@ -10,9 +10,10 @@ usage: ./scripts/run_bench_compare.sh Runs the same nostr-bench suite against: - 1) Parrhesia (temporary prod relay via run_e2e_suite.sh) - 2) strfry (ephemeral instance) — optional, skipped if not in PATH - 3) nostr-rs-relay (ephemeral sqlite instance) — optional, skipped if not in PATH + 1) Parrhesia (Postgres, temporary prod relay via run_e2e_suite.sh) + 2) Parrhesia (in-memory storage, temporary prod relay via run_e2e_suite.sh) + 3) strfry (ephemeral instance) — optional, skipped if not in PATH + 4) nostr-rs-relay (ephemeral sqlite instance) — optional, skipped if not in PATH Environment: PARRHESIA_BENCH_RUNS Number of comparison runs (default: 2) @@ -247,7 +248,7 @@ echo " ${NOSTR_BENCH_VERSION}" echo for run in $(seq 1 "$RUNS"); do - echo "[run ${run}/${RUNS}] Parrhesia" + echo "[run ${run}/${RUNS}] Parrhesia (Postgres)" parrhesia_log="$WORK_DIR/parrhesia_${run}.log" if ! ./scripts/run_nostr_bench.sh all >"$parrhesia_log" 2>&1; then echo "Parrhesia benchmark failed. Log: $parrhesia_log" >&2 @@ -255,6 +256,14 @@ for run in $(seq 1 "$RUNS"); do exit 1 fi + echo "[run ${run}/${RUNS}] Parrhesia (Memory)" + parrhesia_memory_log="$WORK_DIR/parrhesia_memory_${run}.log" + if ! PARRHESIA_BENCH_STORAGE_BACKEND=memory ./scripts/run_nostr_bench.sh all >"$parrhesia_memory_log" 2>&1; then + echo "Parrhesia memory benchmark failed. Log: $parrhesia_memory_log" >&2 + tail -n 120 "$parrhesia_memory_log" >&2 || true + exit 1 + fi + if (( HAS_STRFRY )); then echo "[run ${run}/${RUNS}] strfry" strfry_log="$WORK_DIR/strfry_${run}.log" @@ -364,6 +373,7 @@ function loadRuns(prefix) { } const parrhesiaRuns = loadRuns("parrhesia"); +const parrhesiaMemoryRuns = loadRuns("parrhesia_memory"); const strfryRuns = hasStrfry ? loadRuns("strfry") : []; const nostrRsRuns = hasNostrRs ? loadRuns("nostr_rs_relay") : []; @@ -382,7 +392,10 @@ function summarise(allRuns) { return out; } -const summary = { parrhesia: summarise(parrhesiaRuns) }; +const summary = { + parrhesia: summarise(parrhesiaRuns), + parrhesiaMemory: summarise(parrhesiaMemoryRuns), +}; if (hasStrfry) summary.strfry = summarise(strfryRuns); if (hasNostrRs) summary.nostrRsRelay = summarise(nostrRsRuns); @@ -404,16 +417,22 @@ const metricLabels = [ ["req throughput (MiB/s) ↑", "reqSizeMiBS"], ]; -const headers = ["metric", "parrhesia"]; +const headers = ["metric", "parrhesia-pg", "parrhesia-memory"]; if (hasStrfry) headers.push("strfry"); if (hasNostrRs) headers.push("nostr-rs-relay"); +headers.push("memory/parrhesia"); if (hasStrfry) headers.push("strfry/parrhesia"); if (hasNostrRs) headers.push("nostr-rs/parrhesia"); const rows = metricLabels.map(([label, key]) => { - const row = [label, toFixed(summary.parrhesia[key])]; + const row = [ + label, + toFixed(summary.parrhesia[key]), + toFixed(summary.parrhesiaMemory[key]), + ]; if (hasStrfry) row.push(toFixed(summary.strfry[key])); if (hasNostrRs) row.push(toFixed(summary.nostrRsRelay[key])); + row.push(ratioVsParrhesia("parrhesiaMemory", key)); if (hasStrfry) row.push(ratioVsParrhesia("strfry", key)); if (hasNostrRs) row.push(ratioVsParrhesia("nostrRsRelay", key)); return row; @@ -444,8 +463,10 @@ if (hasStrfry || hasNostrRs) { console.log("Run details:"); for (let i = 0; i < runs; i += 1) { const p = parrhesiaRuns[i]; + const pm = parrhesiaMemoryRuns[i]; let line = ` run ${i + 1}: ` + - `parrhesia(echo_tps=${toFixed(p.echoTps, 0)}, event_tps=${toFixed(p.eventTps, 0)}, req_tps=${toFixed(p.reqTps, 0)}, connect_avg_ms=${toFixed(p.connectAvgMs, 0)})`; + `parrhesia-pg(echo_tps=${toFixed(p.echoTps, 0)}, event_tps=${toFixed(p.eventTps, 0)}, req_tps=${toFixed(p.reqTps, 0)}, connect_avg_ms=${toFixed(p.connectAvgMs, 0)})` + + ` | parrhesia-memory(echo_tps=${toFixed(pm.echoTps, 0)}, event_tps=${toFixed(pm.eventTps, 0)}, req_tps=${toFixed(pm.reqTps, 0)}, connect_avg_ms=${toFixed(pm.connectAvgMs, 0)})`; if (hasStrfry) { const s = strfryRuns[i]; line += ` | strfry(echo_tps=${toFixed(s.echoTps, 0)}, event_tps=${toFixed(s.eventTps, 0)}, req_tps=${toFixed(s.reqTps, 0)}, connect_avg_ms=${toFixed(s.connectAvgMs, 0)})`; diff --git a/scripts/run_e2e_suite.sh b/scripts/run_e2e_suite.sh index d159ee8..55db194 100755 --- a/scripts/run_e2e_suite.sh +++ b/scripts/run_e2e_suite.sh @@ -19,6 +19,8 @@ if [[ "$MIX_ENV" != "test" && "$MIX_ENV" != "prod" ]]; then fi export MIX_ENV +SKIP_ECTO="${PARRHESIA_E2E_SKIP_ECTO:-0}" + SUITE_SLUG="$(printf '%s' "$SUITE_NAME" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '_')" SUITE_UPPER="$(printf '%s' "$SUITE_SLUG" | tr '[:lower:]' '[:upper:]')" PORT_ENV_VAR="PARRHESIA_${SUITE_UPPER}_E2E_RELAY_PORT" @@ -56,14 +58,16 @@ if [[ -z "${DATABASE_URL:-}" ]]; then fi fi -if [[ "$MIX_ENV" == "test" ]]; then - PARRHESIA_TEST_HTTP_PORT=0 mix ecto.drop --quiet --force || true - PARRHESIA_TEST_HTTP_PORT=0 mix ecto.create --quiet - PARRHESIA_TEST_HTTP_PORT=0 mix ecto.migrate --quiet -else - mix ecto.drop --quiet --force || true - mix ecto.create --quiet - mix ecto.migrate --quiet +if [[ "$SKIP_ECTO" != "1" ]]; then + if [[ "$MIX_ENV" == "test" ]]; then + PARRHESIA_TEST_HTTP_PORT=0 mix ecto.drop --quiet --force || true + PARRHESIA_TEST_HTTP_PORT=0 mix ecto.create --quiet + PARRHESIA_TEST_HTTP_PORT=0 mix ecto.migrate --quiet + else + mix ecto.drop --quiet --force || true + mix ecto.create --quiet + mix ecto.migrate --quiet + fi fi SERVER_LOG="${ROOT_DIR}/.${SUITE_SLUG}-e2e-server.log" @@ -75,7 +79,7 @@ cleanup() { wait "$SERVER_PID" 2>/dev/null || true fi - if [[ "${PARRHESIA_E2E_DROP_DB_ON_EXIT:-0}" == "1" ]]; then + if [[ "$SKIP_ECTO" != "1" && "${PARRHESIA_E2E_DROP_DB_ON_EXIT:-0}" == "1" ]]; then if [[ "$MIX_ENV" == "test" ]]; then PARRHESIA_TEST_HTTP_PORT=0 mix ecto.drop --quiet --force || true else diff --git a/scripts/run_nostr_bench.sh b/scripts/run_nostr_bench.sh index 1f668fc..f38f357 100755 --- a/scripts/run_nostr_bench.sh +++ b/scripts/run_nostr_bench.sh @@ -13,6 +13,9 @@ usage: Runs nostr-bench against a temporary Parrhesia prod server started via ./scripts/run_e2e_suite.sh. +Benchmark target: + PARRHESIA_BENCH_STORAGE_BACKEND postgres|memory (default: postgres) + Pool tuning: POOL_SIZE optional override for prod pool size DB_QUEUE_TARGET_MS optional Repo queue target override @@ -39,6 +42,10 @@ Default "all" run can be tuned via env vars: PARRHESIA_BENCH_REQ_RATE (default: 50) PARRHESIA_BENCH_REQ_LIMIT (default: 10) PARRHESIA_BENCH_KEEPALIVE_SECONDS (default: 5) + +By default benchmark runs also lift relay limits so the benchmark client, not +relay-side ceilings, is the bottleneck. Set `PARRHESIA_BENCH_LIFT_LIMITS=0` to +disable that behavior. EOF } @@ -63,11 +70,54 @@ if [[ "$MODE" == "all" && $# -gt 0 ]]; then exit 1 fi -if [[ -z "${PGDATABASE:-}" ]]; then - export PGDATABASE="parrhesia_bench_prod_$(date +%s)_$RANDOM" +BENCH_STORAGE_BACKEND="${PARRHESIA_BENCH_STORAGE_BACKEND:-postgres}" +case "$BENCH_STORAGE_BACKEND" in + postgres|memory) + ;; + *) + echo "PARRHESIA_BENCH_STORAGE_BACKEND must be postgres or memory, got: ${BENCH_STORAGE_BACKEND}" >&2 + exit 1 + ;; +esac + +export PARRHESIA_STORAGE_BACKEND="$BENCH_STORAGE_BACKEND" +export PARRHESIA_ENABLE_EXPIRATION_WORKER="${PARRHESIA_ENABLE_EXPIRATION_WORKER:-0}" +export PARRHESIA_ENABLE_PARTITION_RETENTION_WORKER="${PARRHESIA_ENABLE_PARTITION_RETENTION_WORKER:-0}" + +if [[ "${PARRHESIA_BENCH_LIFT_LIMITS:-1}" == "1" ]]; then + export PARRHESIA_PUBLIC_MAX_CONNECTIONS="${PARRHESIA_PUBLIC_MAX_CONNECTIONS:-infinity}" + export PARRHESIA_LIMITS_MAX_FRAME_BYTES="${PARRHESIA_LIMITS_MAX_FRAME_BYTES:-16777216}" + export PARRHESIA_LIMITS_MAX_EVENT_BYTES="${PARRHESIA_LIMITS_MAX_EVENT_BYTES:-4194304}" + export PARRHESIA_LIMITS_MAX_FILTERS_PER_REQ="${PARRHESIA_LIMITS_MAX_FILTERS_PER_REQ:-1024}" + export PARRHESIA_LIMITS_MAX_FILTER_LIMIT="${PARRHESIA_LIMITS_MAX_FILTER_LIMIT:-100000}" + export PARRHESIA_LIMITS_MAX_TAGS_PER_EVENT="${PARRHESIA_LIMITS_MAX_TAGS_PER_EVENT:-4096}" + export PARRHESIA_LIMITS_MAX_TAG_VALUES_PER_FILTER="${PARRHESIA_LIMITS_MAX_TAG_VALUES_PER_FILTER:-4096}" + export PARRHESIA_LIMITS_IP_MAX_EVENT_INGEST_PER_WINDOW="${PARRHESIA_LIMITS_IP_MAX_EVENT_INGEST_PER_WINDOW:-1000000}" + export PARRHESIA_LIMITS_RELAY_MAX_EVENT_INGEST_PER_WINDOW="${PARRHESIA_LIMITS_RELAY_MAX_EVENT_INGEST_PER_WINDOW:-1000000}" + export PARRHESIA_LIMITS_MAX_SUBSCRIPTIONS_PER_CONNECTION="${PARRHESIA_LIMITS_MAX_SUBSCRIPTIONS_PER_CONNECTION:-4096}" + export PARRHESIA_LIMITS_MAX_EVENT_FUTURE_SKEW_SECONDS="${PARRHESIA_LIMITS_MAX_EVENT_FUTURE_SKEW_SECONDS:-31536000}" + export PARRHESIA_LIMITS_MAX_EVENT_INGEST_PER_WINDOW="${PARRHESIA_LIMITS_MAX_EVENT_INGEST_PER_WINDOW:-1000000}" + export PARRHESIA_LIMITS_AUTH_MAX_AGE_SECONDS="${PARRHESIA_LIMITS_AUTH_MAX_AGE_SECONDS:-31536000}" + export PARRHESIA_LIMITS_MAX_OUTBOUND_QUEUE="${PARRHESIA_LIMITS_MAX_OUTBOUND_QUEUE:-65536}" + export PARRHESIA_LIMITS_OUTBOUND_DRAIN_BATCH_SIZE="${PARRHESIA_LIMITS_OUTBOUND_DRAIN_BATCH_SIZE:-4096}" + export PARRHESIA_LIMITS_MAX_NEGENTROPY_PAYLOAD_BYTES="${PARRHESIA_LIMITS_MAX_NEGENTROPY_PAYLOAD_BYTES:-1048576}" + export PARRHESIA_LIMITS_MAX_NEGENTROPY_SESSIONS_PER_CONNECTION="${PARRHESIA_LIMITS_MAX_NEGENTROPY_SESSIONS_PER_CONNECTION:-256}" + export PARRHESIA_LIMITS_MAX_NEGENTROPY_TOTAL_SESSIONS="${PARRHESIA_LIMITS_MAX_NEGENTROPY_TOTAL_SESSIONS:-100000}" + export PARRHESIA_LIMITS_MAX_NEGENTROPY_ITEMS_PER_SESSION="${PARRHESIA_LIMITS_MAX_NEGENTROPY_ITEMS_PER_SESSION:-1000000}" fi -export PARRHESIA_E2E_DROP_DB_ON_EXIT="${PARRHESIA_E2E_DROP_DB_ON_EXIT:-1}" +if [[ "$BENCH_STORAGE_BACKEND" == "memory" ]]; then + export PARRHESIA_E2E_SKIP_ECTO="${PARRHESIA_E2E_SKIP_ECTO:-1}" + export PARRHESIA_E2E_DROP_DB_ON_EXIT=0 + export PARRHESIA_MODERATION_CACHE_ENABLED="${PARRHESIA_MODERATION_CACHE_ENABLED:-0}" +else + if [[ -z "${PGDATABASE:-}" ]]; then + export PGDATABASE="parrhesia_bench_prod_$(date +%s)_$RANDOM" + fi + + export PARRHESIA_E2E_SKIP_ECTO="${PARRHESIA_E2E_SKIP_ECTO:-0}" + export PARRHESIA_E2E_DROP_DB_ON_EXIT="${PARRHESIA_E2E_DROP_DB_ON_EXIT:-1}" +fi PARRHESIA_E2E_MIX_ENV="prod" \ exec ./scripts/run_e2e_suite.sh \ diff --git a/test/parrhesia/storage_test.exs b/test/parrhesia/storage_test.exs index 048fc4a..a762130 100644 --- a/test/parrhesia/storage_test.exs +++ b/test/parrhesia/storage_test.exs @@ -1,6 +1,7 @@ defmodule Parrhesia.StorageTest do use Parrhesia.IntegrationCase, async: false + alias Parrhesia.PostgresRepos alias Parrhesia.Storage test "resolves default storage modules" do @@ -26,4 +27,23 @@ defmodule Parrhesia.StorageTest do Storage.events() end end + + test "postgres repos are disabled for non-postgres storage backends" do + [{:config, previous}] = :ets.lookup(Parrhesia.Config, :config) + + updated_storage = + previous + |> Map.get(:storage, []) + |> Keyword.put(:backend, :memory) + + :ets.insert(Parrhesia.Config, {:config, Map.put(previous, :storage, updated_storage)}) + + on_exit(fn -> + :ets.insert(Parrhesia.Config, {:config, previous}) + end) + + refute PostgresRepos.postgres_enabled?() + refute PostgresRepos.separate_read_pool_enabled?() + assert PostgresRepos.started_repos() == [] + end end