File: rings.g

package info (click to toggle)
gap-scscp 2.3.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,704 kB
  • sloc: xml: 1,247; sh: 389; makefile: 19
file content (156 lines) | stat: -rw-r--r-- 5,700 bytes parent folder | download | duplicates (2)
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;