Ver a proveniência

ft: 代码修改

master
SisMaker há 3 anos
ascendente
cometimento
0e82803605
2 ficheiros alterados com 238 adições e 238 eliminações
  1. +147
    -147
      src/messages/tpMsgRS.erl
  2. +91
    -91
      src/messages/tpMsgSD.erl

+ 147
- 147
src/messages/tpMsgRS.erl Ver ficheiro

@ -3,199 +3,199 @@
-include("eTpf.hrl").
-export([
pfs/1 %%
, pfm/1 %%
pfs/1 %%
, pfm/2 %%
]).
-record(state, {
meta = #{} :: map(),
senders = #{} :: #{pid() => pos_integer()},
receivers = #{} :: #{pid() => pos_integer()},
pairs = #{} :: #{{pid(), pid()} => pos_integer()},
nonExisting = #{} :: #{pid() => pos_integer()},
lastMsgs = #{} :: #{pid() => atom()}
meta = #{} :: map(),
senders = #{} :: #{pid() => pos_integer()},
receivers = #{} :: #{pid() => pos_integer()},
pairs = #{} :: #{{pid(), pid()} => pos_integer()},
nonExisting = #{} :: #{pid() => pos_integer()},
lastMsgs = #{} :: #{pid() => atom()}
}).
-spec pfs(file:filename_all()) -> ok.
pfs(InputFile) ->
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{}, InputFile),
flush(FinalState).
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{}, InputFile),
flush(FinalState).
-spec pfm(file:filename()) -> ok.
pfm(InputFiles) ->
PfFiles = filelib:wildcard(InputFiles),
doPfm(PfFiles, #state{}).
-spec pfm(file:filename(), filelib:dirname()) -> ok.
pfm(InputFiles, Cwd) ->
PfFiles = filelib:wildcard(InputFiles, Cwd),
doPfm(PfFiles, #state{}).
doPfm([], State) ->
flush(State);
flush(State);
doPfm([InputFile | PfFiles], State) ->
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
%% @todo Later we may want to look at the latency of gen_server call/reply.
%% @todo Later we may want to look at particular messages, have some sort of callback.
handleEvent({send, From, _, Info, ?eTpfHole}, State = #state{meta = Meta}) ->
NewMeta =
case Meta of
#{From := OldInfo} ->
Meta#{From => maps:merge(OldInfo, Info)};
_ ->
Meta#{From => Info}
end,
State#state{meta = NewMeta};
NewMeta =
case Meta of
#{From := OldInfo} ->
Meta#{From => maps:merge(OldInfo, Info)};
_ ->
Meta#{From => Info}
end,
State#state{meta = NewMeta};
handleEvent({send, From, _, Msg, To}, State = #state{senders = Senders, receivers = Receivers, pairs = Pairs, lastMsgs = LastMsgs}) ->
SendersCnt = maps:get(From, Senders, 0),
ReceiversCnt = maps:get(To, Receivers, 0),
PairsCnt = maps:get({From, To}, Pairs, 0),
State#state{
senders = Senders#{From => SendersCnt + 1},
receivers = Receivers#{To => ReceiversCnt + 1},
pairs = Pairs#{{From, To} => PairsCnt + 1},
lastMsgs = LastMsgs#{From => Msg}
};
SendersCnt = maps:get(From, Senders, 0),
ReceiversCnt = maps:get(To, Receivers, 0),
PairsCnt = maps:get({From, To}, Pairs, 0),
State#state{
senders = Senders#{From => SendersCnt + 1},
receivers = Receivers#{To => ReceiversCnt + 1},
pairs = Pairs#{{From, To} => PairsCnt + 1},
lastMsgs = LastMsgs#{From => Msg}
};
handleEvent({send_to_non_existing_process, From, _, Msg, _}, State = #state{nonExisting = NonExisting, lastMsgs = LastMsgs}) ->
Count = maps:get(From, NonExisting, 0),
State#state{
nonExisting = NonExisting#{From => Count + 1},
lastMsgs = LastMsgs#{From => Msg}};
Count = maps:get(From, NonExisting, 0),
State#state{
nonExisting = NonExisting#{From => Count + 1},
lastMsgs = LastMsgs#{From => Msg}};
%% Ignore all other events. We only care about messages.
handleEvent(_, State) ->
State.
State.
%% Output of the profiling.
flush(State) ->
flushMostActiveSenders(State),
flushMostActiveReceivers(State),
flush_most_non_existing(State),
flushMostActivePairUnidirectional(State),
flushMostActivePairBidirectional(State),
io:format("~n"),
flushDigraph(State),
ok.
flushMostActiveSenders(State),
flushMostActiveReceivers(State),
flush_most_non_existing(State),
flushMostActivePairUnidirectional(State),
flushMostActivePairBidirectional(State),
io:format("~n"),
flushDigraph(State),
ok.
flushMostActiveSenders(State = #state{senders = Senders}) ->
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Senders))), 1, 100),
formatByCnt(<<"They sent the most messages">>, List, State).
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Senders))), 1, 100),
formatByCnt(<<"They sent the most messages">>, List, State).
flushMostActiveReceivers(State = #state{receivers = Receivers}) ->
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Receivers))), 1, 100),
formatByCnt(<<"They received the most messages">>, List, State).
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Receivers))), 1, 100),
formatByCnt(<<"They received the most messages">>, List, State).
flush_most_non_existing(State = #state{nonExisting = NonExisting}) ->
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(NonExisting))), 1, 100),
formatByCnt(<<"They sent the most messages to dead processes">>, List, State).
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(NonExisting))), 1, 100),
formatByCnt(<<"They sent the most messages to dead processes">>, List, State).
formatByCnt(Title, List, State) ->
MsgCols = case io:columns() of {ok, Cols} -> Cols;_ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"Process ID Count (Label) OR Message sent~n"
"---------- ----- -----------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{Prefix, Label, Suffix} = labelOrMsg(P, State),
io:format("~-15w ~-10b ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [P, C, Prefix, Label, 5, Suffix])
end || {P, C} <- List
],
ok.
MsgCols = case io:columns() of {ok, Cols} -> Cols;_ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"Process ID Count (Label) OR Message sent~n"
"---------- ----- -----------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{Prefix, Label, Suffix} = labelOrMsg(P, State),
io:format("~-15w ~-10b ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [P, C, Prefix, Label, 5, Suffix])
end || {P, C} <- List
],
ok.
labelOrMsg(P, #state{meta = Meta, lastMsgs = LastMsgs}) ->
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
{"(", PT, ")"};
_ ->
{"", maps:get(P, LastMsgs, '<none>'), ""}
end.
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
{"(", PT, ")"};
_ ->
{"", maps:get(P, LastMsgs, '<none>'), ""}
end.
flushMostActivePairUnidirectional(State = #state{pairs = Pairs}) ->
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Pairs))), 1, 100),
Title = <<"They sent the most messages to one other process">>,
MsgCols = case io:columns() of {ok, Cols} -> Cols; _ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"From pid To pid Count (Label) OR Message sent~n"
"-------- ------ ----- -----------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{Prefix, Label, Suffix} = labelOrMsg(F, State),
io:format("~-15w ~-15w ~-10b ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [F, T, C, Prefix, Label, 5, Suffix])
end || {{F, T}, C} <- List
],
ok.
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(Pairs))), 1, 100),
Title = <<"They sent the most messages to one other process">>,
MsgCols = case io:columns() of {ok, Cols} -> Cols; _ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"From pid To pid Count (Label) OR Message sent~n"
"-------- ------ ----- -----------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{Prefix, Label, Suffix} = labelOrMsg(F, State),
io:format("~-15w ~-15w ~-10b ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [F, T, C, Prefix, Label, 5, Suffix])
end || {{F, T}, C} <- List
],
ok.
flushMostActivePairBidirectional(State = #state{pairs = Pairs}) ->
TemPairs = maps:fold(fun mergePairs/3, #{}, Pairs),
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(TemPairs))), 1, 100),
Title = <<"They sent the most messages to each other">>,
MsgCols = case io:columns() of {ok, Cols} -> Cols;_ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"Count Pid 1 (Label) OR Message sent~n"
" Pid 2 by the corresponding process~n"
"----- ----- ----------------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{FPrefix, FLabel, FSuffix} = labelOrMsg(F, State),
{TPrefix, TLabel, TSuffix} = labelOrMsg(T, State),
io:format(
"~-10b ~-15w ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n"
" ~-15w ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [C, F, FPrefix, FLabel, 5, FSuffix, T, TPrefix, TLabel, 5, TSuffix])
end || {{F, T}, C} <- List
],
ok.
TemPairs = maps:fold(fun mergePairs/3, #{}, Pairs),
List = lists:sublist(lists:reverse(lists:keysort(2, maps:to_list(TemPairs))), 1, 100),
Title = <<"They sent the most messages to each other">>,
MsgCols = case io:columns() of {ok, Cols} -> Cols;_ -> 80 end,
io:format(
"~n~s~n~s~n~n"
"Count Pid 1 (Label) OR Message sent~n"
" Pid 2 by the corresponding process~n"
"----- ----- ----------------------------~n",
[Title, lists:duplicate(byte_size(Title), $=)]
),
[
begin
{FPrefix, FLabel, FSuffix} = labelOrMsg(F, State),
{TPrefix, TLabel, TSuffix} = labelOrMsg(T, State),
io:format(
"~-10b ~-15w ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n"
" ~-15w ~s~" ++ integer_to_list(MsgCols) ++ "P~s~n", [C, F, FPrefix, FLabel, 5, FSuffix, T, TPrefix, TLabel, 5, TSuffix])
end || {{F, T}, C} <- List
],
ok.
flushDigraph(#state{pairs = Pairs} = State) ->
TemPairs = maps:fold(fun groupPairs/3, #{}, Pairs),
List = maps:to_list(TemPairs),
HeaderBin =
<<"digraph {\n"
" concentrate=true;\n"
" splines=ortho;\n"
" edge [arrowhead=none, labelfontsize=12.0, minlen=3];\n"
"\n">>,
writeEvents(List, State, HeaderBin),
io:format(
"The file digraph.gv was created. Use GraphViz to make a PNG.~n"
"$ dot -Tpng -O digraph.gv~n"
"~n"
"You can also edit the file to remove uninteresting processes.~n"
"One line in the file is equal to a connection between two processes.~n"),
ok.
TemPairs = maps:fold(fun groupPairs/3, #{}, Pairs),
List = maps:to_list(TemPairs),
HeaderBin =
<<"digraph {\n"
" concentrate=true;\n"
" splines=ortho;\n"
" edge [arrowhead=none, labelfontsize=12.0, minlen=3];\n"
"\n">>,
writeEvents(List, State, HeaderBin),
io:format(
"The file digraph.gv was created. Use GraphViz to make a PNG.~n"
"$ dot -Tpng -O digraph.gv~n"
"~n"
"You can also edit the file to remove uninteresting processes.~n"
"One line in the file is equal to a connection between two processes.~n"),
ok.
writeEvents([], _State, BinAcc) ->
LastBinAcc = <<BinAcc/binary, "}\n">>,
ok = file:write_file(<<"digraph.gv">>, LastBinAcc);
LastBinAcc = <<BinAcc/binary, "}\n">>,
ok = file:write_file(<<"digraph.gv">>, LastBinAcc);
writeEvents([{{F, T}, {FC, TC}} | List], State, BinAcc) ->
EventBin = eFmt:formatBin(<<" \"~w~s\" -> \"~w~s\" [taillabel=~b, headlabel=~b];~n">>, [F, label(F, State), T, label(T, State), FC, TC]),
writeEvents(List, State, <<BinAcc/binary, EventBin/binary>>).
EventBin = eFmt:formatBin(<<" \"~w~s\" -> \"~w~s\" [taillabel=~b, headlabel=~b];~n">>, [F, label(F, State), T, label(T, State), FC, TC]),
writeEvents(List, State, <<BinAcc/binary, EventBin/binary>>).
label(P, #state{meta = Meta}) ->
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
eFmt:format(<<" (~w)">>, [PT]);
_ ->
<<"">>
end.
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
eFmt:format(<<" (~w)">>, [PT]);
_ ->
<<"">>
end.
mergePairs({From, To}, Count, Acc) ->
Key = case From < To of true -> {From, To};_ -> {To, From} end,
OldCount = maps:get(Key, Acc, 0),
Acc#{Key => OldCount + Count}.
Key = case From < To of true -> {From, To};_ -> {To, From} end,
OldCount = maps:get(Key, Acc, 0),
Acc#{Key => OldCount + Count}.
groupPairs({From, To}, Count, Acc) when From < To ->
Key = {From, To},
{_, AccCount} = maps:get(Key, Acc, {0, 0}),
Acc#{Key => {Count, AccCount}};
Key = {From, To},
{_, AccCount} = maps:get(Key, Acc, {0, 0}),
Acc#{Key => {Count, AccCount}};
groupPairs({From, To}, Count, Acc) ->
Key = {To, From},
{AccCount, _} = maps:get(Key, Acc, {0, 0}),
Acc#{Key => {AccCount, Count}}.
Key = {To, From},
{AccCount, _} = maps:get(Key, Acc, {0, 0}),
Acc#{Key => {AccCount, Count}}.

+ 91
- 91
src/messages/tpMsgSD.erl Ver ficheiro

@ -3,73 +3,73 @@
-include("eTpf.hrl").
-export([
pfs/2 %%
, pfm/2 %%
pfs/2 %%
, pfm/3 %%
]).
-record(state, {
meta = #{} :: map(),
events = [],
pids
meta = #{} :: map(),
events = [],
pids
}).
-spec pfs(file:filename_all(), list()) -> ok.
pfs(InputFile, Pids) ->
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{pids = preparePids(Pids)}, InputFile),
flush(FinalState).
{ok, FinalState} = tpFReader:fold(fun handleEvent/2, #state{pids = preparePids(Pids)}, InputFile),
flush(FinalState).
-spec pfm(file:filename(), list()) -> ok.
pfm(InputFiles, Pids) ->
PfFiles = filelib:wildcard(InputFiles),
doPfm(PfFiles, #state{pids = preparePids(Pids)}).
-spec pfm(file:filename(), filelib:dirname(), list()) -> ok.
pfm(InputFiles, Cwd, Pids) ->
PfFiles = filelib:wildcard(InputFiles, Cwd),
doPfm(PfFiles, #state{pids = preparePids(Pids)}).
doPfm([], State) ->
flush(State);
flush(State);
doPfm([InputFile | PfFiles], State) ->
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
{ok, NewState} = tpFReader:fold(fun handleEvent/2, State, InputFile),
doPfm(PfFiles, NewState).
handleEvent({send, From, _, Info, ?eTpfHole}, State = #state{meta = Meta}) ->
NewMeta =
case Meta of
#{From := OldInfo} ->
Meta#{From => maps:merge(OldInfo, Info)};
_ ->
Meta#{From => Info}
end,
State#state{meta = NewMeta};
NewMeta =
case Meta of
#{From := OldInfo} ->
Meta#{From => maps:merge(OldInfo, Info)};
_ ->
Meta#{From => Info}
end,
State#state{meta = NewMeta};
handleEvent({send, From, _, _, To} = Event, State) ->
maybeKeepEvent(Event, From, To, State);
maybeKeepEvent(Event, From, To, State);
handleEvent({send_to_non_existing_process, From, _, _, To} = Event, State) ->
maybeKeepEvent(Event, From, To, State);
maybeKeepEvent(Event, From, To, State);
handleEvent({spawn, From, _, To, _} = Event, State) ->
maybeKeepEvent(Event, From, To, State);
maybeKeepEvent(Event, From, To, State);
handleEvent({exit, Pid0, _, _} = Event, State = #state{events = Events, pids = Pids}) ->
Pid = hidePidNode(Pid0),
case lists:member(Pid, Pids) of
true ->
State#state{events = [Event | Events]};
_ ->
State
end;
Pid = hidePidNode(Pid0),
case lists:member(Pid, Pids) of
true ->
State#state{events = [Event | Events]};
_ ->
State
end;
%% Ignore all other events. We only care about messages and spawns/exits.
handleEvent(_, State) ->
State.
State.
maybeKeepEvent(Event, From0, To0, State = #state{events = Events, pids = Pids}) ->
From = hidePidNode(From0),
To = hidePidNode(To0),
case {lists:member(From, Pids), lists:member(To, Pids)} of
{true, true} -> State#state{events = [Event | Events]};
_ -> State
end.
From = hidePidNode(From0),
To = hidePidNode(To0),
case {lists:member(From, Pids), lists:member(To, Pids)} of
{true, true} -> State#state{events = [Event | Events]};
_ -> State
end.
preparePids(Pids) ->
Pids.
Pids.
%% [hide_pid_node(Pid) || Pid <- Pids].
hidePidNode(Pid) when is_pid(Pid) ->
Pid;
Pid;
%%hide_pid_node(pid_to_list(Pid));
hidePidNode([$<, _, $. | Tail]) -> "<***." ++ Tail;
hidePidNode([$<, _, _, $. | Tail]) -> "<***." ++ Tail;
@ -79,66 +79,66 @@ hidePidNode([$<, _, _, _, _, _, $. | Tail]) -> "<***." ++ Tail;
hidePidNode(Name) -> Name.
flush(#state{events = Events} = State) ->
%% Sort by timestamp from oldest to newest.
SortEvents = lists:keysort(3, Events),
%% Initialize the formatting state.
put(num_calls, 0),
%% Output everything.
HeaderBin = <<"seqdiag {\n"
" edge_length = 300;\n"
" activation = none;\n"
"\n">>,
writeEvents(SortEvents, State, HeaderBin),
io:format(
"The file seq.diag was created. Use seqdiag to make a PNG.~n"
"$ seqdiag -Tpng --no-transparency seq.diag~n"
"~n"
"To use a custom font, use the -f modifier:~n"
"$ seqdiag -Tpng --no-transparency -f /usr/share/fonts/TTF/verdana.ttf seq.diag~n"
"~n"
"You can also edit the file to remove uninteresting messages.~n"
"One line in the file is equal to a message sent by a process to another.~n"),
ok.
%% Sort by timestamp from oldest to newest.
SortEvents = lists:keysort(3, Events),
%% Initialize the formatting state.
put(num_calls, 0),
%% Output everything.
HeaderBin = <<"seqdiag {\n"
" edge_length = 300;\n"
" activation = none;\n"
"\n">>,
writeEvents(SortEvents, State, HeaderBin),
io:format(
"The file seq.diag was created. Use seqdiag to make a PNG.~n"
"$ seqdiag -Tpng --no-transparency seq.diag~n"
"~n"
"To use a custom font, use the -f modifier:~n"
"$ seqdiag -Tpng --no-transparency -f /usr/share/fonts/TTF/verdana.ttf seq.diag~n"
"~n"
"You can also edit the file to remove uninteresting messages.~n"
"One line in the file is equal to a message sent by a process to another.~n"),
ok.
writeEvents([], _State, BinAcc) ->
LastBinAcc = <<BinAcc/binary, "}\n">>,
ok = file:write_file(<<"seq.diag">>, LastBinAcc);
LastBinAcc = <<BinAcc/binary, "}\n">>,
ok = file:write_file(<<"seq.diag">>, LastBinAcc);
writeEvents([Event | SortEvents], State, BinAcc) ->
EventBin = formatEvent(Event, State),
writeEvents(SortEvents, State, <<BinAcc/binary, EventBin/binary>>).
EventBin = formatEvent(Event, State),
writeEvents(SortEvents, State, <<BinAcc/binary, EventBin/binary>>).
formatEvent({spawn, From, _, To, MFA}, State) ->
eFmt:formatBin(<<" \"~w~s\" ->> \"~w~s\" [label=\"spawn ~9999P\"];~n">>, [From, label(From, State), To, label(To, State), MFA, 8]);
eFmt:formatBin(<<" \"~w~s\" ->> \"~w~s\" [label=\"spawn ~9999P\"];~n">>, [From, label(From, State), To, label(To, State), MFA, 8]);
formatEvent({exit, Pid, _, Reason}, State) ->
PidLabel = label(Pid, State),
eFmt:formatBin(<<" \"~w~s\" ->> \"~w~s\" [label=\"exit ~9999P\"];~n">>, [Pid, PidLabel, Pid, PidLabel, Reason, 8]);
PidLabel = label(Pid, State),
eFmt:formatBin(<<" \"~w~s\" ->> \"~w~s\" [label=\"exit ~9999P\"];~n">>, [Pid, PidLabel, Pid, PidLabel, Reason, 8]);
formatEvent({Type, From, _, {'$gen_call', {From, Ref}, Msg}, To}, State) ->
NumCalls = get(num_calls) + 1,
put(num_calls, NumCalls),
put(Ref, NumCalls),
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"gen:call #~w ~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), NumCalls, Msg, 8]);
NumCalls = get(num_calls) + 1,
put(num_calls, NumCalls),
put(Ref, NumCalls),
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"gen:call #~w ~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), NumCalls, Msg, 8]);
formatEvent(Event = {Type, From, _, {Ref, Msg}, To}, State) ->
case get(Ref) of
undefined ->
defFormatEvent(Event, State);
NumCall ->
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"#~w ~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), NumCall, Msg, 8])
end;
case get(Ref) of
undefined ->
defFormatEvent(Event, State);
NumCall ->
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"#~w ~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), NumCall, Msg, 8])
end;
formatEvent(Event, State) ->
defFormatEvent(Event, State).
defFormatEvent(Event, State).
defFormatEvent({Type, From, _, Msg, To}, State) ->
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), Msg, 8]).
eFmt:formatBin(<<" \"~w~s\" ~s \"~w~s\" [label=\"~9999P\"];~n">>, [From, label(From, State), case Type of send ->
"->"; _ -> "-->" end, To, label(To, State), Msg, 8]).
label(P, #state{meta = Meta}) ->
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
eFmt:formatBin(" (~w)", [PT]);
_ ->
<<"">>
end.
case maps:get(P, Meta, #{}) of
#{process_type := PT} ->
eFmt:formatBin(" (~w)", [PT]);
_ ->
<<"">>
end.

Carregando…
Cancelar
Guardar