okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffaufperf(retrieval): page O(n) rows and retain O(k) resultsa651329

main
3.8 KiB78 linesraw
1%% BEAM calls and returned rows expose bounded work that E2E cannot measure.
2-module(albedo_retrieval_test_support).
3-export([measure/2]).
4
5measure(Owner, Run) ->
6    %% EUnit's inherited inparallel mode can overlap tests from this module.
7    %% Legacy trace patterns are VM-wide, so measurements must not disable
8    %% one another's patterns while a different test is still running.
9    global:trans({?MODULE, self()}, fun() -> measure_locked(Owner, Run) end, [node()]).
10
11measure_locked(Owner, Run) ->
12    Processes = lists:usort([self(), Owner]),
13    Patterns = [
14        {'albedo@harness@search', pages, 3},
15        {'albedo@daemon@conversation', read_input, 2},
16        {'albedo@daemon@conversation', sourced_entry, 3}
17    ],
18    Rows = {'albedo@daemon@store', rows, 4},
19    lists:foreach(fun({Module, _, _}) -> {module, Module} = code:ensure_loaded(Module) end, [Rows | Patterns]),
20    Tracer = spawn(fun() -> collect({counts, 0, 0, 0, 0, 0, #{}}, none) end),
21    lists:foreach(fun(Pattern) -> erlang:trace_pattern(Pattern, true, [local]) end, Patterns),
22    erlang:trace_pattern(Rows, [{'_', [], [{return_trace}]}], [local]),
23    lists:foreach(fun(Pid) -> erlang:trace(Pid, true, [call, {tracer, Tracer}]) end, Processes),
24    try
25        Value = Run(),
26        Tracer ! {result, self(), Processes},
27        receive {measurement, Counts} -> {Value, Counts} end
28    after
29        lists:foreach(fun(Pid) -> erlang:trace(Pid, false, [call]) end, Processes),
30        lists:foreach(fun(Pattern) -> erlang:trace_pattern(Pattern, false, [local]) end, [Rows | Patterns]),
31        exit(Tracer, kill)
32    end.
33
34%% Consume delivery markers in the same mailbox as trace events before
35%% reporting counts, while call tracing remains enabled.
36collect(State, Finish) ->
37    receive
38        {result, Reply, Processes} ->
39            Refs = [erlang:trace_delivered(Pid) || Pid <- Processes],
40            collect(State, {Reply, Refs});
41        {trace_delivered, _, Ref} ->
42            {Reply, Refs} = Finish,
43            case lists:delete(Ref, Refs) of
44                [] ->
45                    {counts, Pages, Decoded, Sources, Nodes, Kept, _} = State,
46                    Reply ! {measurement, {counts, Pages, Decoded, Sources, Nodes, Kept}},
47                    collect(State, none);
48                Pending -> collect(State, {Reply, Pending})
49            end;
50        Event -> collect(event(Event, State), Finish)
51    end.
52
53event({trace, _, call, {'albedo@harness@search', pages, [_, _, Acc]}},
54      {counts, Pages, Decoded, Sources, Nodes, Kept, Queries}) ->
55    Size = case Acc of {page, _, Matches} -> length(Matches); _ -> 0 end,
56    {counts, Pages + 1, Decoded, Sources, Nodes, max(Kept, Size), Queries};
57event({trace, _, call, {'albedo@daemon@conversation', read_input, _}},
58      {counts, Pages, Decoded, Sources, Nodes, Kept, Queries}) ->
59    {counts, Pages, Decoded + 1, Sources, Nodes, Kept, Queries};
60event({trace, _, call, {'albedo@daemon@conversation', sourced_entry, _}},
61      {counts, Pages, Decoded, Sources, Nodes, Kept, Queries}) ->
62    {counts, Pages, Decoded, Sources + 1, Nodes, Kept, Queries};
63event({trace, Pid, call, {'albedo@daemon@store', rows, [_, Sql, _, _]}},
64      {counts, Pages, Decoded, Sources, Nodes, Kept, Queries}) ->
65    IsNodes = case Sql of
66        <<"SELECT id,depth", _/binary>> -> true;
67        <<"SELECT n.id,n.depth", _/binary>> -> true;
68        _ -> false
69    end,
70    {counts, Pages, Decoded, Sources, Nodes, Kept, Queries#{Pid => IsNodes}};
71event({trace, Pid, return_from, {'albedo@daemon@store', rows, 4}, Result},
72      {counts, Pages, Decoded, Sources, Nodes, Kept, Queries}) ->
73    Count = case {maps:get(Pid, Queries, false), Result} of
74        {true, {ok, Values}} when is_list(Values) -> length(Values);
75        _ -> 0
76    end,
77    {counts, Pages, Decoded, Sources, Nodes + Count, Kept, maps:remove(Pid, Queries)};
78event(_, State) -> State.