build: Darwin fix

This commit is contained in:
2026-03-14 02:59:46 +01:00
parent 54a54c026b
commit 63d3e7d55f
5 changed files with 169 additions and 182 deletions

View File

@@ -75,7 +75,8 @@ in {
}); });
nostr-bench = pkgs.callPackage ./nix/nostr-bench.nix {}; nostr-bench = pkgs.callPackage ./nix/nostr-bench.nix {};
in in
with pkgs; [ with pkgs;
[
just just
git git
# Nix code formatter # Nix code formatter
@@ -94,6 +95,8 @@ in {
nostr-bench nostr-bench
# Nostr reference servers # Nostr reference servers
nostr-rs-relay nostr-rs-relay
]
++ lib.optionals pkgs.stdenv.hostPlatform.isx86_64 [
strfry strfry
]; ];
@@ -146,7 +149,7 @@ in {
DROP database template1; DROP database template1;
CREATE DATABASE template1 WITH OWNER = agent CREATE DATABASE template1
ENCODING = 'UTF8' ENCODING = 'UTF8'
TABLESPACE = pg_default TABLESPACE = pg_default
LC_COLLATE = 'de_DE.UTF-8' LC_COLLATE = 'de_DE.UTF-8'

View File

@@ -43,8 +43,6 @@ defmodule Parrhesia.MixProject do
# Test tooling # Test tooling
{:stream_data, "~> 1.0", only: :test}, {:stream_data, "~> 1.0", only: :test},
{:mox, "~> 1.1", only: :test},
{:bypass, "~> 2.1", only: :test},
{:websockex, "~> 0.4", only: :test}, {:websockex, "~> 0.4", only: :test},
# Project tooling # Project tooling

View File

@@ -1,7 +1,6 @@
%{ %{
"bandit": {:hex, :bandit, "1.10.3", "1e5d168fa79ec8de2860d1b4d878d97d4fbbe2fdbe7b0a7d9315a4359d1d4bb9", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "99a52d909c48db65ca598e1962797659e3c0f1d06e825a50c3d75b74a5e2db18"}, "bandit": {:hex, :bandit, "1.10.3", "1e5d168fa79ec8de2860d1b4d878d97d4fbbe2fdbe7b0a7d9315a4359d1d4bb9", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "99a52d909c48db65ca598e1962797659e3c0f1d06e825a50c3d75b74a5e2db18"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"bypass": {:hex, :bypass, "2.1.0", "909782781bf8e20ee86a9cabde36b259d44af8b9f38756173e8f5e2e1fabb9b1", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "d9b5df8fa5b7a6efa08384e9bbecfe4ce61c77d28a4282f79e02f1ef78d96b80"},
"cowboy": {:hex, :cowboy, "2.14.2", "4008be1df6ade45e4f2a4e9e2d22b36d0b5aba4e20b0a0d7049e28d124e34847", [:make, :rebar3], [{:cowlib, ">= 2.16.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "569081da046e7b41b5df36aa359be71a0c8874e5b9cff6f747073fc57baf1ab9"}, "cowboy": {:hex, :cowboy, "2.14.2", "4008be1df6ade45e4f2a4e9e2d22b36d0b5aba4e20b0a0d7049e28d124e34847", [:make, :rebar3], [{:cowlib, ">= 2.16.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "569081da046e7b41b5df36aa359be71a0c8874e5b9cff6f747073fc57baf1ab9"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.16.0", "54592074ebbbb92ee4746c8a8846e5605052f29309d3a873468d76cdf932076f", [:make, :rebar3], [], "hexpm", "7f478d80d66b747344f0ea7708c187645cfcc08b11aa424632f78e25bf05db51"}, "cowlib": {:hex, :cowlib, "2.16.0", "54592074ebbbb92ee4746c8a8846e5605052f29309d3a873468d76cdf932076f", [:make, :rebar3], [], "hexpm", "7f478d80d66b747344f0ea7708c187645cfcc08b11aa424632f78e25bf05db51"},
@@ -19,9 +18,7 @@
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"},
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
"mox": {:hex, :mox, "1.2.0", "a2cd96b4b80a3883e3100a221e8adc1b98e4c3a332a8fc434c39526babafd5b3", [:mix], [{:nimble_ownership, "~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}], "hexpm", "c7b92b3cc69ee24a7eeeaf944cd7be22013c52fcb580c1f33f50845ec821089a"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_ownership": {:hex, :nimble_ownership, "1.0.2", "fa8a6f2d8c592ad4d79b2ca617473c6aefd5869abfa02563a77682038bf916cf", [:mix], [], "hexpm", "098af64e1f6f8609c6672127cfe9e9590a5d3fcdd82bc17a377b8692fd81a879"},
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
"owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"}, "owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"},
"plug": {:hex, :plug, "1.19.1", "09bac17ae7a001a68ae393658aa23c7e38782be5c5c00c80be82901262c394c0", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "560a0017a8f6d5d30146916862aaf9300b7280063651dd7e532b8be168511e62"}, "plug": {:hex, :plug, "1.19.1", "09bac17ae7a001a68ae393658aa23c7e38782be5c5c00c80be82901262c394c0", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "560a0017a8f6d5d30146916862aaf9300b7280063651dd7e532b8be168511e62"},

View File

@@ -11,8 +11,8 @@ usage:
Runs the same nostr-bench suite against: Runs the same nostr-bench suite against:
1) Parrhesia (temporary prod relay via run_e2e_suite.sh) 1) Parrhesia (temporary prod relay via run_e2e_suite.sh)
2) strfry (ephemeral instance) 2) strfry (ephemeral instance) — optional, skipped if not in PATH
3) nostr-rs-relay (ephemeral sqlite instance) 3) nostr-rs-relay (ephemeral sqlite instance) — optional, skipped if not in PATH
Environment: Environment:
PARRHESIA_BENCH_RUNS Number of comparison runs (default: 2) PARRHESIA_BENCH_RUNS Number of comparison runs (default: 2)
@@ -50,19 +50,28 @@ if ! command -v nostr-bench >/dev/null 2>&1; then
exit 1 exit 1
fi fi
if ! command -v strfry >/dev/null 2>&1; then # port_listening PORT — cross-platform check (Darwin: lsof, Linux: ss)
echo "strfry not found in PATH. Enter devenv shell first." >&2 port_listening() {
exit 1 local port="$1"
if command -v ss >/dev/null 2>&1; then
ss -ltn | grep -q ":${port} "
else
lsof -iTCP:"${port}" -sTCP:LISTEN -P -n >/dev/null 2>&1
fi
}
HAS_STRFRY=0
if command -v strfry >/dev/null 2>&1; then
HAS_STRFRY=1
else
echo "strfry not found in PATH — skipping strfry benchmarks"
fi fi
if ! command -v nostr-rs-relay >/dev/null 2>&1; then HAS_NOSTR_RS=0
echo "nostr-rs-relay not found in PATH. Enter devenv shell first." >&2 if command -v nostr-rs-relay >/dev/null 2>&1; then
exit 1 HAS_NOSTR_RS=1
fi else
echo "nostr-rs-relay not found in PATH — skipping nostr-rs-relay benchmarks"
if ! command -v ss >/dev/null 2>&1; then
echo "ss command not found; cannot detect strfry readiness." >&2
exit 1
fi fi
RUNS="${PARRHESIA_BENCH_RUNS:-2}" RUNS="${PARRHESIA_BENCH_RUNS:-2}"
@@ -98,8 +107,16 @@ resolve_strfry_version() {
printf '%s\n' "$cli_version" printf '%s\n' "$cli_version"
} }
STRFRY_VERSION=""
if (( HAS_STRFRY )); then
STRFRY_VERSION="$(resolve_strfry_version)" STRFRY_VERSION="$(resolve_strfry_version)"
fi
NOSTR_RS_RELAY_VERSION=""
if (( HAS_NOSTR_RS )); then
NOSTR_RS_RELAY_VERSION="$(nostr-rs-relay --version 2>/dev/null | head -n 1 | tr -d '\r')" NOSTR_RS_RELAY_VERSION="$(nostr-rs-relay --version 2>/dev/null | head -n 1 | tr -d '\r')"
fi
NOSTR_BENCH_VERSION="$(nostr-bench --version 2>/dev/null | head -n 1 | tr -d '\r')" NOSTR_BENCH_VERSION="$(nostr-bench --version 2>/dev/null | head -n 1 | tr -d '\r')"
export PARRHESIA_BENCH_CONNECT_COUNT="${PARRHESIA_BENCH_CONNECT_COUNT:-200}" export PARRHESIA_BENCH_CONNECT_COUNT="${PARRHESIA_BENCH_CONNECT_COUNT:-200}"
@@ -158,7 +175,7 @@ EOF
STRFRY_PID=$! STRFRY_PID=$!
for _ in {1..100}; do for _ in {1..100}; do
if ss -ltn | grep -q ":${port} "; then if port_listening "${port}"; then
return 0 return 0
fi fi
sleep 0.1 sleep 0.1
@@ -198,7 +215,7 @@ EOF
NOSTR_RS_PID=$! NOSTR_RS_PID=$!
for _ in {1..100}; do for _ in {1..100}; do
if ss -ltn | grep -q ":${port} "; then if port_listening "${port}"; then
return 0 return 0
fi fi
sleep 0.1 sleep 0.1
@@ -220,8 +237,12 @@ stop_nostr_rs_relay() {
echo "Running ${RUNS} comparison run(s)..." echo "Running ${RUNS} comparison run(s)..."
echo "Versions:" echo "Versions:"
echo " parrhesia ${PARRHESIA_VERSION}" echo " parrhesia ${PARRHESIA_VERSION}"
if (( HAS_STRFRY )); then
echo " ${STRFRY_VERSION}" echo " ${STRFRY_VERSION}"
fi
if (( HAS_NOSTR_RS )); then
echo " ${NOSTR_RS_RELAY_VERSION}" echo " ${NOSTR_RS_RELAY_VERSION}"
fi
echo " ${NOSTR_BENCH_VERSION}" echo " ${NOSTR_BENCH_VERSION}"
echo echo
@@ -234,6 +255,7 @@ for run in $(seq 1 "$RUNS"); do
exit 1 exit 1
fi fi
if (( HAS_STRFRY )); then
echo "[run ${run}/${RUNS}] strfry" echo "[run ${run}/${RUNS}] strfry"
strfry_log="$WORK_DIR/strfry_${run}.log" strfry_log="$WORK_DIR/strfry_${run}.log"
strfry_port=$((49000 + run)) strfry_port=$((49000 + run))
@@ -246,7 +268,9 @@ for run in $(seq 1 "$RUNS"); do
exit 1 exit 1
fi fi
stop_strfry stop_strfry
fi
if (( HAS_NOSTR_RS )); then
echo "[run ${run}/${RUNS}] nostr-rs-relay" echo "[run ${run}/${RUNS}] nostr-rs-relay"
nostr_rs_log="$WORK_DIR/nostr_rs_relay_${run}.log" nostr_rs_log="$WORK_DIR/nostr_rs_relay_${run}.log"
nostr_rs_port=$((50000 + run)) nostr_rs_port=$((50000 + run))
@@ -259,17 +283,20 @@ for run in $(seq 1 "$RUNS"); do
exit 1 exit 1
fi fi
stop_nostr_rs_relay stop_nostr_rs_relay
fi
echo echo
done done
node - "$WORK_DIR" "$RUNS" <<'NODE' node - "$WORK_DIR" "$RUNS" "$HAS_STRFRY" "$HAS_NOSTR_RS" <<'NODE'
const fs = require("node:fs"); const fs = require("node:fs");
const path = require("node:path"); const path = require("node:path");
const workDir = process.argv[2]; const workDir = process.argv[2];
const runs = Number(process.argv[3]); const runs = Number(process.argv[3]);
const hasStrfry = process.argv[4] === "1";
const hasNostrRs = process.argv[5] === "1";
function parseLog(filePath) { function parseLog(filePath) {
const content = fs.readFileSync(filePath, "utf8"); const content = fs.readFileSync(filePath, "utf8");
@@ -337,124 +364,61 @@ function loadRuns(prefix) {
} }
const parrhesiaRuns = loadRuns("parrhesia"); const parrhesiaRuns = loadRuns("parrhesia");
const strfryRuns = loadRuns("strfry"); const strfryRuns = hasStrfry ? loadRuns("strfry") : [];
const nostrRsRuns = loadRuns("nostr_rs_relay"); const nostrRsRuns = hasNostrRs ? loadRuns("nostr_rs_relay") : [];
const summary = { const metrics = [
parrhesia: { "connectAvgMs", "connectMaxMs",
connectAvgMs: mean(parrhesiaRuns.map((m) => m.connectAvgMs)), "echoTps", "echoSizeMiBS",
connectMaxMs: mean(parrhesiaRuns.map((m) => m.connectMaxMs)), "eventTps", "eventSizeMiBS",
echoTps: mean(parrhesiaRuns.map((m) => m.echoTps)), "reqTps", "reqSizeMiBS",
echoSizeMiBS: mean(parrhesiaRuns.map((m) => m.echoSizeMiBS)), ];
eventTps: mean(parrhesiaRuns.map((m) => m.eventTps)),
eventSizeMiBS: mean(parrhesiaRuns.map((m) => m.eventSizeMiBS)), function summarise(allRuns) {
reqTps: mean(parrhesiaRuns.map((m) => m.reqTps)), const out = {};
reqSizeMiBS: mean(parrhesiaRuns.map((m) => m.reqSizeMiBS)), for (const m of metrics) {
}, out[m] = mean(allRuns.map((r) => r[m]));
strfry: { }
connectAvgMs: mean(strfryRuns.map((m) => m.connectAvgMs)), return out;
connectMaxMs: mean(strfryRuns.map((m) => m.connectMaxMs)), }
echoTps: mean(strfryRuns.map((m) => m.echoTps)),
echoSizeMiBS: mean(strfryRuns.map((m) => m.echoSizeMiBS)), const summary = { parrhesia: summarise(parrhesiaRuns) };
eventTps: mean(strfryRuns.map((m) => m.eventTps)), if (hasStrfry) summary.strfry = summarise(strfryRuns);
eventSizeMiBS: mean(strfryRuns.map((m) => m.eventSizeMiBS)), if (hasNostrRs) summary.nostrRsRelay = summarise(nostrRsRuns);
reqTps: mean(strfryRuns.map((m) => m.reqTps)),
reqSizeMiBS: mean(strfryRuns.map((m) => m.reqSizeMiBS)),
},
nostrRsRelay: {
connectAvgMs: mean(nostrRsRuns.map((m) => m.connectAvgMs)),
connectMaxMs: mean(nostrRsRuns.map((m) => m.connectMaxMs)),
echoTps: mean(nostrRsRuns.map((m) => m.echoTps)),
echoSizeMiBS: mean(nostrRsRuns.map((m) => m.echoSizeMiBS)),
eventTps: mean(nostrRsRuns.map((m) => m.eventTps)),
eventSizeMiBS: mean(nostrRsRuns.map((m) => m.eventSizeMiBS)),
reqTps: mean(nostrRsRuns.map((m) => m.reqTps)),
reqSizeMiBS: mean(nostrRsRuns.map((m) => m.reqSizeMiBS)),
},
};
function ratioVsParrhesia(serverKey, metric) { function ratioVsParrhesia(serverKey, metric) {
const p = summary.parrhesia[metric]; const p = summary.parrhesia[metric];
const other = summary[serverKey][metric]; const other = summary[serverKey]?.[metric];
if (!Number.isFinite(p) || !Number.isFinite(other) || p === 0) return "n/a"; if (!Number.isFinite(p) || !Number.isFinite(other) || p === 0) return "n/a";
return `${(other / p).toFixed(2)}x`; return `${(other / p).toFixed(2)}x`;
} }
const rows = [ const metricLabels = [
[ ["connect avg latency (ms) ↓", "connectAvgMs"],
"connect avg latency (ms) ↓", ["connect max latency (ms) ↓", "connectMaxMs"],
toFixed(summary.parrhesia.connectAvgMs), ["echo throughput (TPS) ↑", "echoTps"],
toFixed(summary.strfry.connectAvgMs), ["echo throughput (MiB/s) ↑", "echoSizeMiBS"],
toFixed(summary.nostrRsRelay.connectAvgMs), ["event throughput (TPS) ↑", "eventTps"],
ratioVsParrhesia("strfry", "connectAvgMs"), ["event throughput (MiB/s) ↑", "eventSizeMiBS"],
ratioVsParrhesia("nostrRsRelay", "connectAvgMs"), ["req throughput (TPS) ↑", "reqTps"],
], ["req throughput (MiB/s) ↑", "reqSizeMiBS"],
[
"connect max latency (ms) ↓",
toFixed(summary.parrhesia.connectMaxMs),
toFixed(summary.strfry.connectMaxMs),
toFixed(summary.nostrRsRelay.connectMaxMs),
ratioVsParrhesia("strfry", "connectMaxMs"),
ratioVsParrhesia("nostrRsRelay", "connectMaxMs"),
],
[
"echo throughput (TPS) ↑",
toFixed(summary.parrhesia.echoTps),
toFixed(summary.strfry.echoTps),
toFixed(summary.nostrRsRelay.echoTps),
ratioVsParrhesia("strfry", "echoTps"),
ratioVsParrhesia("nostrRsRelay", "echoTps"),
],
[
"echo throughput (MiB/s) ↑",
toFixed(summary.parrhesia.echoSizeMiBS),
toFixed(summary.strfry.echoSizeMiBS),
toFixed(summary.nostrRsRelay.echoSizeMiBS),
ratioVsParrhesia("strfry", "echoSizeMiBS"),
ratioVsParrhesia("nostrRsRelay", "echoSizeMiBS"),
],
[
"event throughput (TPS) ↑",
toFixed(summary.parrhesia.eventTps),
toFixed(summary.strfry.eventTps),
toFixed(summary.nostrRsRelay.eventTps),
ratioVsParrhesia("strfry", "eventTps"),
ratioVsParrhesia("nostrRsRelay", "eventTps"),
],
[
"event throughput (MiB/s) ↑",
toFixed(summary.parrhesia.eventSizeMiBS),
toFixed(summary.strfry.eventSizeMiBS),
toFixed(summary.nostrRsRelay.eventSizeMiBS),
ratioVsParrhesia("strfry", "eventSizeMiBS"),
ratioVsParrhesia("nostrRsRelay", "eventSizeMiBS"),
],
[
"req throughput (TPS) ↑",
toFixed(summary.parrhesia.reqTps),
toFixed(summary.strfry.reqTps),
toFixed(summary.nostrRsRelay.reqTps),
ratioVsParrhesia("strfry", "reqTps"),
ratioVsParrhesia("nostrRsRelay", "reqTps"),
],
[
"req throughput (MiB/s) ↑",
toFixed(summary.parrhesia.reqSizeMiBS),
toFixed(summary.strfry.reqSizeMiBS),
toFixed(summary.nostrRsRelay.reqSizeMiBS),
ratioVsParrhesia("strfry", "reqSizeMiBS"),
ratioVsParrhesia("nostrRsRelay", "reqSizeMiBS"),
],
]; ];
const headers = [ const headers = ["metric", "parrhesia"];
"metric", if (hasStrfry) headers.push("strfry");
"parrhesia", if (hasNostrRs) headers.push("nostr-rs-relay");
"strfry", if (hasStrfry) headers.push("strfry/parrhesia");
"nostr-rs-relay", if (hasNostrRs) headers.push("nostr-rs/parrhesia");
"strfry/parrhesia",
"nostr-rs/parrhesia", const rows = metricLabels.map(([label, key]) => {
]; const row = [label, toFixed(summary.parrhesia[key])];
if (hasStrfry) row.push(toFixed(summary.strfry[key]));
if (hasNostrRs) row.push(toFixed(summary.nostrRsRelay[key]));
if (hasStrfry) row.push(ratioVsParrhesia("strfry", key));
if (hasNostrRs) row.push(ratioVsParrhesia("nostrRsRelay", key));
return row;
});
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i].length))); const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i].length)));
function fmtRow(cols) { function fmtRow(cols) {
@@ -471,18 +435,25 @@ for (const row of rows) {
} }
console.log("\nLegend: ↑ higher is better, ↓ lower is better."); console.log("\nLegend: ↑ higher is better, ↓ lower is better.");
if (hasStrfry || hasNostrRs) {
console.log("Ratio columns are server/parrhesia (for ↓ metrics, <1.00x means that server is faster).\n"); console.log("Ratio columns are server/parrhesia (for ↓ metrics, <1.00x means that server is faster).\n");
} else {
console.log("");
}
console.log("Run details:"); console.log("Run details:");
for (let i = 0; i < runs; i += 1) { for (let i = 0; i < runs; i += 1) {
const p = parrhesiaRuns[i]; const p = parrhesiaRuns[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)})`;
if (hasStrfry) {
const s = strfryRuns[i]; 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)})`;
}
if (hasNostrRs) {
const n = nostrRsRuns[i]; const n = nostrRsRuns[i];
console.log( line += ` | nostr-rs-relay(echo_tps=${toFixed(n.echoTps, 0)}, event_tps=${toFixed(n.eventTps, 0)}, req_tps=${toFixed(n.reqTps, 0)}, connect_avg_ms=${toFixed(n.connectAvgMs, 0)})`;
` 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)}) | ` + console.log(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)}) | ` +
`nostr-rs-relay(echo_tps=${toFixed(n.echoTps, 0)}, event_tps=${toFixed(n.eventTps, 0)}, req_tps=${toFixed(n.reqTps, 0)}, connect_avg_ms=${toFixed(n.connectAvgMs, 0)})`
);
} }
NODE NODE

View File

@@ -2,6 +2,24 @@
set -euo pipefail set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# Check if the marmot-ts submodule is initialised
if [[ ! -f "$ROOT_DIR/marmot-ts/package.json" ]]; then
echo "marmot-ts submodule is not initialised." >&2
if [[ -t 0 ]]; then
read -rp "Initialise it now? [y/N] " answer
if [[ "$answer" =~ ^[Yy]$ ]]; then
git -C "$ROOT_DIR" submodule update --init marmot-ts
else
echo "Skipping marmot e2e tests."
exit 0
fi
else
echo "Run 'git submodule update --init marmot-ts' to initialise it." >&2
exit 1
fi
fi
cd "$ROOT_DIR/marmot-ts" cd "$ROOT_DIR/marmot-ts"
if [[ ! -d node_modules ]]; then if [[ ! -d node_modules ]]; then