Skip to content

Instantly share code, notes, and snippets.

@cooldaemon
Created April 6, 2012 16:46
Show Gist options
  • Save cooldaemon/2321245 to your computer and use it in GitHub Desktop.
Save cooldaemon/2321245 to your computer and use it in GitHub Desktop.
Sticky Write Lock vs Write Lock.
-module(sticky_write_vs_write).
-author('cooldaemon@gmail.com').
-export([init_primary/0, init_secondary/0, run/3]).
-record(store, {key, value}).
init_primary() ->
{ok, _} = net_kernel:start(['primary@localhost', shortnames]),
true = erlang:set_cookie(node(), 'secret_cookie'),
mnesia:start(),
mnesia:change_config(extra_db_nodes, ['secondary@localhost']),
mnesia:delete_table(store),
{atomic, ok} = mnesia:create_table(
store,
[
{record_name, store},
{type, set},
{attributes, record_info(fields, store)},
{ram_copies, [node(), 'secondary@localhost']}
]
),
ok.
init_secondary() ->
% os:cmd("epmd&"),
{ok, _} = net_kernel:start(['secondary@localhost', shortnames]),
true = erlang:set_cookie(node(), 'secret_cookie'),
mnesia:start(),
ok.
run(TryCount, ProcessCount, WriteCount) ->
Pids = lists:map(
fun (_) -> spawn_link(fun writer_process/0) end,
lists:seq(1, ProcessCount)
),
do(TryCount, Pids, WriteCount),
lists:foreach(fun (Pid) -> Pid ! finish end, Pids).
writer_process() ->
receive
{run, Count, Function, ReturnPid} ->
lists:foreach(fun (_) -> Function() end, lists:seq(1, Count)),
ReturnPid ! {self(), ok};
finish ->
exit(normal);
Other ->
io:fwrite("Writer received unknown message: ~p~n", [Other])
end,
writer_process().
do(0, _, _) -> ok;
do(TryCount, WriterPids, WriterCount) ->
io:fwrite("--<reduction:~p>--~n", [TryCount]),
lists:foreach(
fun ({F, TargetName}) ->
{ok, [RunTime, WallClock]} = write(WriterPids, WriterCount, F),
io:fwrite("~s: ~p(~p)ms~n", [TargetName, RunTime, WallClock])
end,
[
{fun mnesia:write/1, "write"},
{fun mnesia:s_write/1, "sticky_write"}
]
),
do(TryCount-1, WriterPids, WriterCount).
run_writer(Pids, Count, Function) ->
lists:foreach(fun (Pid) ->
Pid ! {run, Count, Function, self()}
end, Pids),
lists:foreach(fun (Pid) ->
receive {Pid, _} -> ok end
end, Pids),
ok.
benchmark(TargetFunction) ->
lists:foreach(fun statistics/1, [runtime, wall_clock]),
Result = TargetFunction(),
Times = lists:map(
fun (Type) -> {_, T} = statistics(Type), T end,
[runtime, wall_clock]
),
{Result, Times}.
write(WriterPids, WriteCount, WriteFunction) ->
benchmark(fun () ->
run_writer(WriterPids, WriteCount, fun () ->
mnesia:activity(
transaction,
WriteFunction,
[#store{key = foo, value = bar}]
)
end)
end).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment