WIP: Chain manager projection store flowchart goop
This commit is contained in:
parent
ca5ddb2cf1
commit
dbcc87b4a4
2 changed files with 184 additions and 0 deletions
109
prototype/poc-machi/docs/machi/chain-mgmt-flowchart.dot
Normal file
109
prototype/poc-machi/docs/machi/chain-mgmt-flowchart.dot
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
digraph {
|
||||||
|
compound=true
|
||||||
|
label="Machi chain management flowchart (sample)";
|
||||||
|
|
||||||
|
node[shape="box", style="rounded"]
|
||||||
|
start;
|
||||||
|
node[shape="box", style="rounded", label="stop1"]
|
||||||
|
stop1;
|
||||||
|
node[shape="box", style="rounded", label="stop2"]
|
||||||
|
stop2;
|
||||||
|
node[shape="box", style="rounded"]
|
||||||
|
crash;
|
||||||
|
|
||||||
|
subgraph clustera {
|
||||||
|
node[shape="parallelogram", style="", label="Set retry counter = 0"]
|
||||||
|
a05_retry;
|
||||||
|
node[shape="parallelogram", style="", label="Create P_newprop @ epoch E+1\nbased on P_current @ epoch E"]
|
||||||
|
a10_create;
|
||||||
|
node[shape="parallelogram", style="", label="Get latest public projection, P_latest"]
|
||||||
|
a20_get;
|
||||||
|
node[shape="diamond", style="", label="Epoch(P_latest) > Epoch(P_current)\norelse\nP_latest was not unanimous"]
|
||||||
|
a30_epoch;
|
||||||
|
node[shape="diamond", style="", label="Epoch(P_latest) == Epoch(P_current)"]
|
||||||
|
a40_epochequal;
|
||||||
|
node[shape="diamond", style="", label="P_latest == P_current"]
|
||||||
|
a50_equal;
|
||||||
|
}
|
||||||
|
|
||||||
|
subgraph clustera100 {
|
||||||
|
node[shape="diamond", style="", label="Write P_newprop to everyone"]
|
||||||
|
a100_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
subgraph clusterb {
|
||||||
|
node[shape="diamond", style="", label="P_latest was unanimous?"]
|
||||||
|
b10_unanimous;
|
||||||
|
node[shape="diamond", style="", label="Retry counter too big?"]
|
||||||
|
b20_counter;
|
||||||
|
node[shape="diamond", style="", label="Rank(P_latest) >= Rank(P_newprop)"]
|
||||||
|
b30_rank;
|
||||||
|
node[shape="diamond", style="", label="P_latest.upi == P_newprop.upi\nand also\nPlatest.repairing == P_newprop.repairing"]
|
||||||
|
b40_condc;
|
||||||
|
node[shape="square", style="", label="P_latest author is\ntoo slow, let's try!"]
|
||||||
|
b45_lets;
|
||||||
|
node[shape="parallelogram", style="", label="P_newprop is better than P_latest.\nSet P_newprop.epoch = P_latest.epoch + 1."]
|
||||||
|
b50_better;
|
||||||
|
}
|
||||||
|
|
||||||
|
subgraph clusterc {
|
||||||
|
node[shape="diamond", style="", label="Is Move(P_current, P_latest) ok?"]
|
||||||
|
c10_move;
|
||||||
|
node[shape="parallelogram", style="", label="Tell Author(P_latest) to rewrite\nwith a bigger epoch number"]
|
||||||
|
c20_tell;
|
||||||
|
}
|
||||||
|
|
||||||
|
subgraph clusterd {
|
||||||
|
node[shape="diamond", style="", label="Use P_latest as the\nnew P_current"]
|
||||||
|
d10_use;
|
||||||
|
}
|
||||||
|
|
||||||
|
start -> a05_retry;
|
||||||
|
|
||||||
|
a05_retry -> a10_create;
|
||||||
|
a10_create -> a20_get;
|
||||||
|
a20_get -> a30_epoch;
|
||||||
|
a30_epoch -> a40_epochequal[label="false"];
|
||||||
|
a30_epoch -> b10_unanimous[label="true"];
|
||||||
|
a40_epochequal -> a50_equal[label="true"];
|
||||||
|
a40_epochequal -> crash[label="falseXX"];
|
||||||
|
a50_equal -> stop1[label="true"];
|
||||||
|
a50_equal -> b20_counter[label="false"];
|
||||||
|
|
||||||
|
a100_write -> a10_create;
|
||||||
|
|
||||||
|
b10_unanimous -> c10_move[label="yes"];
|
||||||
|
b10_unanimous -> b20_counter[label="no"];
|
||||||
|
b20_counter -> b45_lets[label="true"];
|
||||||
|
b20_counter -> b30_rank[label="false"];
|
||||||
|
b30_rank -> b40_condc[label="false"];
|
||||||
|
b30_rank -> c20_tell[label="true"];
|
||||||
|
b40_condc -> b50_better[label="false"];
|
||||||
|
b40_condc -> c20_tell[label="true"];
|
||||||
|
b45_lets -> b50_better;
|
||||||
|
b50_better -> a100_write;
|
||||||
|
|
||||||
|
c10_move -> d10_use[label="yes"];
|
||||||
|
c10_move -> a100_write[label="no"];
|
||||||
|
c20_tell -> b50_better;
|
||||||
|
|
||||||
|
d10_use -> stop2;
|
||||||
|
|
||||||
|
{rank=same; clustera clusterb clusterc clusterd};
|
||||||
|
|
||||||
|
// {rank=same; a10_create b10_unanimous c10_move d10_use stop2};
|
||||||
|
// {rank=same; a20_get b20_counter c20_tell};
|
||||||
|
// {rank=same; a30_epoch b40_condc};
|
||||||
|
// {rank=same; a40_epochequal b40_condc crash};
|
||||||
|
// {rank=same; stop1 a50_equal b50_better};
|
||||||
|
|
||||||
|
// if_valid;
|
||||||
|
//
|
||||||
|
// start -> input;
|
||||||
|
// input -> if_valid;
|
||||||
|
// if_valid -> message[label="no"];
|
||||||
|
// if_valid -> end[label="yes"];
|
||||||
|
// message -> input;
|
||||||
|
|
||||||
|
// {rank=same; message input}
|
||||||
|
}
|
|
@ -36,6 +36,81 @@
|
||||||
-export([make_projection_summary/1]).
|
-export([make_projection_summary/1]).
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
%% NOTE NOTE NOTE NOTE NOTE NOTE
|
||||||
|
%% The sketch below is old ... the flowchart is newer.
|
||||||
|
%% TODO todo delete these comments when the flowchart
|
||||||
|
%% and its implementation have been debugged
|
||||||
|
%% NOTE NOTE NOTE NOTE NOTE NOTE
|
||||||
|
|
||||||
|
%% Sketch for chain management simulator: the 'monitor'
|
||||||
|
%%
|
||||||
|
%% Principles:
|
||||||
|
%% * Monitor based on only one dimension of the FLU's inherent state:
|
||||||
|
%% up or down
|
||||||
|
%% * Plus one additional aspect that is experienced by the external
|
||||||
|
%% repair coordinator: not_started, in_progress, finished_ok, or
|
||||||
|
%% finished_failed
|
||||||
|
%% * For simulation purposes, start first with the repair coordinator
|
||||||
|
%% happening completely by magic, e.g., an oracle implemented by the
|
||||||
|
%% test harness.
|
||||||
|
%% - Then add more complexity, slowly, and only when necessary.
|
||||||
|
%% * Assumption for ease-of-implementation: assume that the repair
|
||||||
|
%% coordinator will be the head of the chain (or some process that
|
||||||
|
%% is managed by the head).
|
||||||
|
%% - So the simulator need only worry about the head making any
|
||||||
|
%% decisions about changes in repair state.
|
||||||
|
%%
|
||||||
|
%% Implementation:
|
||||||
|
%%
|
||||||
|
%% A. Calculate a local projection, P_{newprop} @ epoch E+1 that is
|
||||||
|
%% based on the current projection P_{current} @ epoch E.
|
||||||
|
%% - NOTE: This has side-effects in the current simulator:
|
||||||
|
%% e.g., newenv changing perception of up/down state
|
||||||
|
%% and other network partition effects.
|
||||||
|
%%
|
||||||
|
%% B. Get the latest public projection, P_{latest}. Then consider:
|
||||||
|
%%
|
||||||
|
%% B1a). If Epoch(P_{latest}) == Epoch(P_{current}), then goto step C.
|
||||||
|
%%
|
||||||
|
%% B1b). If Epoch(P_{latest}) < Epoch(P_{current}), then we have a
|
||||||
|
%% serious invariant violation/logic problem. Shouldn't happen,
|
||||||
|
%% but keep an eye out for it anyway.
|
||||||
|
%%
|
||||||
|
%% B1c). If Epoch(P_{latest}) > Epoch(P_{current}), then some other
|
||||||
|
%% manager has noticed a change.
|
||||||
|
%%
|
||||||
|
%% If we haven't stopped yet, then continue:
|
||||||
|
%%
|
||||||
|
%% B2a). If P_{latest} was read unanimously, then use it as the new
|
||||||
|
%% P_{current}. Then stop.
|
||||||
|
%%
|
||||||
|
%% B2b). If P_{latest} is not unanimous, then compare rank.
|
||||||
|
%%
|
||||||
|
%% - If Rank(P_{latest}) >= Rank(P_{newprop}), then we encourage
|
||||||
|
%% the author to re-write this projection with a bigger epoch
|
||||||
|
%% number.
|
||||||
|
%% - If the counter has exceeded some # of tries, F=2?, then
|
||||||
|
%% goto Step D instead.
|
||||||
|
%% - Set a counter of the # of times that we've encouraged
|
||||||
|
%% the author to re-write.
|
||||||
|
%% - Sleep a while, then goto A.
|
||||||
|
%%
|
||||||
|
%% - If Rank(P_{latest}) < Rank(P_{newprop}) and also
|
||||||
|
%% P_{latest}.upi == P_{newprop}.upi and also
|
||||||
|
%% P_{latest}.repairing == P_{newprop}.repairing, then our
|
||||||
|
%% proposal P_{newprop} isn't anything substantially new.
|
||||||
|
%% - Use the same encouragement & retry loop as described above.
|
||||||
|
%%
|
||||||
|
%% - If Rank(P_{latest}) < Rank(P_{newprop}) (last case)...
|
||||||
|
%% ... our proposal is better. Goto step D.
|
||||||
|
%%
|
||||||
|
%% C. If P_{latest}.upi == P_{newprop}.upi and also
|
||||||
|
%% P_{latest}.repairing == P_{newprop}.repairing, then our proposal
|
||||||
|
%% P_{newprop} isn't anything substantially new. Stop.
|
||||||
|
%%
|
||||||
|
%% D. Write P_{newprop} to everyone. Then goto A.
|
||||||
|
|
||||||
-export([test_calc_projection/2,
|
-export([test_calc_projection/2,
|
||||||
test_calc_proposed_projection/1,
|
test_calc_proposed_projection/1,
|
||||||
test_write_proposed_projection/1,
|
test_write_proposed_projection/1,
|
||||||
|
|
Loading…
Reference in a new issue