git.iko.soy/distributed-process
on remove-table-api help sign in
62 lines 1.6 kB history raw
1%% can be run via escript if desired...
2-module(ring).
4-export([main/1]).
6-record(opts, {
7 ring_size = 1 :: non_neg_integer(),
8 iterations = 1 :: non_neg_integer()
9}).
11main(Argv) when is_list(Argv) ->
12 Opts = parse_args(Argv),
13 {Time, ok} = timer:tc(fun() -> run(Opts) end),
14 io:format("elapsed (wallclock) time: ~pms~n", [Time / 1000]).
16run(#opts{ ring_size=RingSize, iterations=SendCount }) ->
17 Self = self(),
18 Msg = {"foobar", "baz"},
19 Pid = make_ring(RingSize, Self),
20 [Pid ! Msg || _ <- lists:seq(1, SendCount)],
21 collect(SendCount).
23collect(0) ->
24 ok;
25collect(N) ->
26 receive
27 {"foobar", "baz"} -> collect(N - 1);
28 Other -> exit({unexpected_message, Other})
29 end.
31-spec(make_ring(integer(), pid()) -> pid()).
32make_ring(0, NextPid) ->
33 go(NextPid);
34make_ring(NumProcs, NextPid) ->
35 make_ring(NumProcs - 1, go(NextPid)).
37-spec(go(pid()) -> pid()).
38go(NextPid) ->
39 spawn(fun() -> relay(NextPid) end).
41-spec(relay(pid()) -> no_return()).
42relay(NextPid) ->
43 receive
44 {_, _}=Msg -> NextPid ! Msg, relay(NextPid)
45 end.
47-spec(parse_args([string()]) -> #opts{}).
48parse_args(Argv) ->
49 lists:foldl(fun parse_args/2, #opts{}, Argv).
51parse_args(("-r" ++ Val), Opts) ->
52 Sz = check_positive(ring_size, list_to_integer(Val)),
53 Opts#opts{ ring_size = Sz };
54parse_args(("-i" ++ Val), Opts) ->
55 Iter = check_positive(iterations, list_to_integer(Val)),
56 Opts#opts{ iterations = Iter }.
58check_positive(K, N) when N < 1 ->
59 io:format("~p must be >= 1~n", [K]),
60 error({K, N});
61check_positive(_, N) ->
62 N.