GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
#
# 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;