test/build: Stability, compatibility
This commit is contained in:
11
justfile
11
justfile
@@ -1,5 +1,4 @@
|
|||||||
set shell := ["bash", "-euo", "pipefail", "-c"]
|
set shell := ["bash", "-euo", "pipefail", "-c"]
|
||||||
set script-interpreter := ["bash", "-euo", "pipefail"]
|
|
||||||
|
|
||||||
repo_root := justfile_directory()
|
repo_root := justfile_directory()
|
||||||
|
|
||||||
@@ -12,8 +11,9 @@ help topic="":
|
|||||||
@cd "{{repo_root}}" && ./scripts/just_help.sh "{{topic}}"
|
@cd "{{repo_root}}" && ./scripts/just_help.sh "{{topic}}"
|
||||||
|
|
||||||
# Raw e2e harness commands.
|
# Raw e2e harness commands.
|
||||||
[script]
|
e2e subcommand *args:
|
||||||
e2e subcommand="help" *args:
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
cd "{{repo_root}}"
|
cd "{{repo_root}}"
|
||||||
subcommand="{{subcommand}}"
|
subcommand="{{subcommand}}"
|
||||||
|
|
||||||
@@ -40,8 +40,9 @@ e2e subcommand="help" *args:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Benchmark flows (local/cloud/history + direct relay targets).
|
# Benchmark flows (local/cloud/history + direct relay targets).
|
||||||
[script]
|
bench subcommand *args:
|
||||||
bench subcommand="help" *args:
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
cd "{{repo_root}}"
|
cd "{{repo_root}}"
|
||||||
subcommand="{{subcommand}}"
|
subcommand="{{subcommand}}"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,17 @@ defmodule Parrhesia.Storage.Adapters.Memory.Store do
|
|||||||
audit_logs: []
|
audit_logs: []
|
||||||
}
|
}
|
||||||
|
|
||||||
def ensure_started, do: start_store()
|
def start_link(opts \\ []) do
|
||||||
|
name = Keyword.get(opts, :name, @name)
|
||||||
|
Agent.start_link(&init_state/0, name: name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_started do
|
||||||
|
case Process.whereis(@name) do
|
||||||
|
pid when is_pid(pid) -> :ok
|
||||||
|
nil -> start_store()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def put_event(event_id, event) when is_binary(event_id) and is_map(event) do
|
def put_event(event_id, event) when is_binary(event_id) and is_map(event) do
|
||||||
:ok = ensure_started()
|
:ok = ensure_started()
|
||||||
@@ -159,28 +169,72 @@ defmodule Parrhesia.Storage.Adapters.Memory.Store do
|
|||||||
defp normalize_reduce_result(next_acc), do: next_acc
|
defp normalize_reduce_result(next_acc), do: next_acc
|
||||||
|
|
||||||
def get(fun) do
|
def get(fun) do
|
||||||
:ok = ensure_started()
|
with_store(fn pid -> Agent.get(pid, fun) end)
|
||||||
Agent.get(@name, fun)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(fun) do
|
def update(fun) do
|
||||||
:ok = ensure_started()
|
with_store(fn pid -> Agent.update(pid, fun) end)
|
||||||
Agent.update(@name, fun)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_and_update(fun) do
|
def get_and_update(fun) do
|
||||||
:ok = ensure_started()
|
with_store(fn pid -> Agent.get_and_update(pid, fun) end)
|
||||||
Agent.get_and_update(@name, fun)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp start_store do
|
defp start_store do
|
||||||
case Agent.start_link(&init_state/0, name: @name) do
|
case start_link() do
|
||||||
{:ok, _pid} -> :ok
|
{:ok, _pid} ->
|
||||||
{:error, {:already_started, _pid}} -> :ok
|
:ok
|
||||||
{:error, reason} -> {:error, reason}
|
|
||||||
|
{:error, {:already_started, pid}} ->
|
||||||
|
if Process.alive?(pid) do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
wait_for_store_exit(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:error, reason}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp with_store(fun, attempts \\ 2)
|
||||||
|
|
||||||
|
defp with_store(fun, attempts) when attempts > 0 do
|
||||||
|
:ok = ensure_started()
|
||||||
|
|
||||||
|
case Process.whereis(@name) do
|
||||||
|
pid when is_pid(pid) ->
|
||||||
|
try do
|
||||||
|
fun.(pid)
|
||||||
|
catch
|
||||||
|
:exit, reason ->
|
||||||
|
if noproc_exit?(reason) and attempts > 1 do
|
||||||
|
with_store(fun, attempts - 1)
|
||||||
|
else
|
||||||
|
exit(reason)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
nil ->
|
||||||
|
with_store(fun, attempts - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp with_store(_fun, 0), do: exit(:noproc)
|
||||||
|
|
||||||
|
defp wait_for_store_exit(pid) do
|
||||||
|
ref = Process.monitor(pid)
|
||||||
|
|
||||||
|
receive do
|
||||||
|
{:DOWN, ^ref, :process, ^pid, _reason} -> start_store()
|
||||||
|
after
|
||||||
|
100 -> start_store()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp noproc_exit?({:noproc, _details}), do: true
|
||||||
|
defp noproc_exit?(_reason), do: false
|
||||||
|
|
||||||
defp init_state do
|
defp init_state do
|
||||||
ensure_tables_started()
|
ensure_tables_started()
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,19 @@ defmodule Parrhesia.Storage.Supervisor do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(_init_arg) do
|
def init(_init_arg) do
|
||||||
children = moderation_cache_children() ++ PostgresRepos.started_repos()
|
children =
|
||||||
|
memory_store_children() ++ moderation_cache_children() ++ PostgresRepos.started_repos()
|
||||||
|
|
||||||
Supervisor.init(children, strategy: :one_for_one)
|
Supervisor.init(children, strategy: :one_for_one)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp memory_store_children do
|
||||||
|
case Application.get_env(:parrhesia, :storage, [])[:backend] do
|
||||||
|
:memory -> [Parrhesia.Storage.Adapters.Memory.Store]
|
||||||
|
_other -> []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp moderation_cache_children do
|
defp moderation_cache_children do
|
||||||
if PostgresRepos.postgres_enabled?() and
|
if PostgresRepos.postgres_enabled?() and
|
||||||
Application.get_env(:parrhesia, :moderation_cache_enabled, true) do
|
Application.get_env(:parrhesia, :moderation_cache_enabled, true) do
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ defmodule Parrhesia.Storage.Adapters.Memory.AdapterTest do
|
|||||||
alias Parrhesia.Storage.Adapters.Memory.Events
|
alias Parrhesia.Storage.Adapters.Memory.Events
|
||||||
alias Parrhesia.Storage.Adapters.Memory.Groups
|
alias Parrhesia.Storage.Adapters.Memory.Groups
|
||||||
alias Parrhesia.Storage.Adapters.Memory.Moderation
|
alias Parrhesia.Storage.Adapters.Memory.Moderation
|
||||||
|
alias Parrhesia.Storage.Adapters.Memory.Store
|
||||||
|
|
||||||
|
setup do
|
||||||
|
start_supervised!(Store)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "memory adapter supports basic behavior contract operations" do
|
test "memory adapter supports basic behavior contract operations" do
|
||||||
event_id = String.duplicate("a", 64)
|
event_id = String.duplicate("a", 64)
|
||||||
|
|||||||
Reference in New Issue
Block a user