1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#############################################################################
#
# Experimental functions for rings workflows, not included in the release.
# Currenly not working (deadlock) after changing return_nothing rules.
#
#############################################################################
RingTest:=function( nrservers, nrsteps, k )
local port, proc;
# in the beginning the external client sends k=0 to the port 26133, e.g.
# NewProcess( "RingTest", [ 2, 10, 0 ], "localhost", 26133 : return_nothing );
Print(k, " \c");
k:=k+1;
if k = nrsteps then
Print( "--> ", k," : THE LIMIT ACHIEVED, TEST STOPPED !!! \n" );
return true;
fi;
port := 26133 + ( k mod nrservers );
Print("--> ", k," : ", port, "\n");
proc:=NewProcess( "RingTest", [ nrservers, nrsteps, k ], "localhost", port : return_nothing );
return true;
end;
LeaderElectionDone:=false;
# For example, to start on 4 servers, enter:
# nr:=4;NewProcess( "LeaderElection", ["init",0,nr], "localhost", 26133) : return_nothing );
LeaderElection:=function( status, id, nr )
local proc, nextport, m;
# status is either "init", "candidate" or "leader"
if not LeaderElectionDone then
nextport := 26133 + ((SCSCPserverPort-26133+1) mod nr);
if status="init" then # id can be anything on the init stage
Print( "Initialising, sending candidate ", [SCSCPserverPort, IO_getpid() ], " to ", nextport, "\n" );
proc:=NewProcess( "LeaderElection", [ "candidate", [ SCSCPserverPort, IO_getpid() ], nr ],
"localhost", nextport : return_nothing );
return true;
elif status="candidate" then
if id[2] = IO_getpid() then
LeaderElectionDone := true;
Print( "Got ", status, " ", id, ". Election done, sending leader ", id, " to ", nextport, "\n" );
proc:=NewProcess( "LeaderElection", [ "leader", id, nr ], "localhost", nextport : return_nothing );
return true;
else
if id[2] < IO_getpid() then
m := id;
else;
m := [ SCSCPserverPort, IO_getpid() ];
fi;
Print( "Got ", status, " ", id, ", sending candidate ", m , " to ", nextport, "\n" );
proc:=NewProcess( "LeaderElection", [ status, m, nr ], "localhost", nextport : return_nothing );
return true;
fi;
else
LeaderElectionDone := true;
Print( "Got ", status, " ", id, ", sending ", status, " ", id, " to ", nextport, "\n" );
proc:=NewProcess( "LeaderElection", [ status, id, nr ], "localhost", nextport : return_nothing );
return true;
fi;
else
Print( "Got ", status, " ", id, ", doing nothing \n" );
return true;
fi;
end;
ResetLeaderElection:=function()
LeaderElectionDone:=false;
Print( "Reset LeaderElectionDone to ", LeaderElectionDone, "\n" );
return true;
end;
# THIS IS AN ATTEMPT TO CREATE THE TORUS WORKFLOW (DEADLOCKING!)
TorusNodesStatus:=[];
TorusNodesOwners:=[];
ResetTorus:=function()
TorusNodesStatus:=[];
TorusNodesOwners:=[];
return true;
end;
UpdateTorusNodesStatus:=function( owner, port, status )
if not IsBound( TorusNodesStatus[port] ) then
Print( "Client ", owner, " setting ", port, " to ", status );
else
Print( "Client ", owner, " switching ", port, " from ", TorusNodesStatus[port], " to ", status );
fi;
if not IsBound( TorusNodesStatus[port] ) then
TorusNodesStatus[port]:=status;
TorusNodesOwners[port]:=owner;
Print(" - OK! \n" );
return true;
elif TorusNodesStatus[port]=true and status=false then
if port in TorusNodesOwners then
Print(" - refused, ", port, " is busy! \n" );
return false;
else
TorusNodesStatus[port]:=false;
TorusNodesOwners[port]:=owner;
Print(" - OK! \n" );
return true;
fi;
elif TorusNodesStatus[port]=false and status=true then
if TorusNodesOwners[port]=owner then
TorusNodesStatus[port]:=true;
TorusNodesOwners[port]:=0;
Print(" - OK! \n" );
return true;
else
Print(" - refused, ", owner, " is not an owner of ", port, " ! \n" );
return false;
fi;
elif TorusNodesStatus[port]=true and status=true then
Print(" - nothing to do! \n" );
return true;
elif TorusNodesStatus[port]=false and status=false then
Print(" - refused! \n" );
return false;
else
Error("UpdateTorusNodesStatus : unhandled combination!\n");
fi;
end;
TorusTest:=function( nrrows, nrcols, nrsteps, k, waiterport )
local port, proc, r, st;
# First start UpdateTorusNodesStatus at port 'waiterport'. Then to begin the test,
# some external client sends k=0 to the port 26133, e.g.
# NewProcess( "TorusTest", [ 2, 2, 10, 0, 26137 ], "localhost", 26133 : return_nothing );
Print("Got ", k, " \c");
k:=k+1;
if k = nrsteps then
Print( "||--> ", k," : THE LIMIT ACHIEVED, TEST STOPPED !!! \n" );
return true;
fi;
r := QuotientRemainder( SCSCPserverPort-26133, nrcols );
port := 26133 + r[1]*nrcols + ((r[2]+1) mod nrcols);
Print("|--> horizontally --> ", k," : ", port, "\n");
repeat
Exec("sleep 5");
st:=EvaluateBySCSCP( "UpdateTorusNodesStatus", [ SCSCPserverPort, port, false ], "localhost", waiterport );
until st.object=true;
proc:=NewProcess( "TorusTest", [ nrrows, nrcols, nrsteps, k, waiterport], "localhost", port : return_nothing );
EvaluateBySCSCP( "UpdateTorusNodesStatus", [ SCSCPserverPort, port, true ], "localhost", waiterport );
port := 26133 + ( (SCSCPserverPort-26133+nrcols ) mod (nrcols*nrrows) );
Print("|--> vertically --> ", k," : ", port, "\n");
repeat
Exec("sleep 5");
st:=EvaluateBySCSCP( "UpdateTorusNodesStatus", [ SCSCPserverPort, port, false ], "localhost", waiterport );
until st.object=true;
proc:=NewProcess( "TorusTest", [ nrrows, nrcols, nrsteps, k, waiterport ], "localhost", port : return_nothing );
EvaluateBySCSCP( "UpdateTorusNodesStatus", [ SCSCPserverPort, port, true ], "localhost", waiterport );
return true;
end;
|