RPCTest.mesa
Andrew Birrell September 7, 1983 6:34 pm
DIRECTORY
BasicTime, Process, Rope, RPC, RPCLupine, UserCredentials;
RPCTest: MONITOR
IMPORTS BasicTime, Process, RPC, RPCLupine, UserCredentials =
BEGIN
-- ******** Parameters ******** --
Finished: SIGNAL = CODE;
signalFinished: BOOLEANTRUE;
extraArgPkts: CARDINAL ← 0;
extraArgLength: RPCLupine.DataLength ← RPCLupine.maxDataLength-1;
argLength: RPCLupine.DataLength ← 1;
extraResPkts: CARDINAL ← 0;
extraResLength: RPCLupine.DataLength ← RPCLupine.maxDataLength;
resLength: RPCLupine.DataLength ← 2;
callDelaySecs: CARDINAL ← 0;
senderGapSecs: CARDINAL ← 0;
receiverGapSecs: CARDINAL ← 0;
callGapSecs: CARDINAL ← 0;
tries: CARDINAL ← 1000;
quit: BOOLEANFALSE;
raiseSignal: BOOLEANFALSE;
resumeSignal: BOOLEANTRUE;
authenticate: BOOLEANTRUE;
gvExport: BOOLEANTRUE;
gvInstance: Rope.ROPE ← UserCredentials.Get[].name;
nongvInstance: Rope.ROPE ← "Tokay";
callerName: RPC.Principal ← gvInstance;
callerKey: RPC.EncryptionKey ← RPC.MakeKey[UserCredentials.Get[].password];
exporterName: RPC.Principal ← callerName;
exporterKey: RPC.EncryptionKey ← callerKey;
userTest: BOOLEANTRUE;
spyWanted: BOOLEANFALSE;
minWanted: BOOLEANTRUE;
caller: PROCESS;
pktSpace: ARRAY[1..RPCLupine.pktOverhead+RPCLupine.maxDataLength] OF WORD;
pkt: RPCLupine.StubPkt = RPCLupine.GetStubPkt[@pktSpace];
import: RPCLupine.ImportHandle ← NIL;
conversation: RPC.Conversation;
-- ******** Hand-crafted stubs ******** --
RemoteSignal: SIGNAL = CODE;
SignalDispatcher: RPCLupine.Dispatcher =
BEGIN
UNTIL lastPkt
DO [callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt] ENDLOOP;
SIGNAL RemoteSignal[];
RETURN[0]
END;
Send: PROC =
BEGIN
[] ← RPCLupine.StartCall[pkt, import, conversation];
FOR p: CARDINAL IN [1..extraArgPkts]
DO RPCLupine.SendPrelimPkt[pkt, extraArgLength];
IF senderGapSecs > 0
THEN Process.Pause[Process.SecondsToTicks[senderGapSecs]];
ENDLOOP;
BEGIN
length: RPCLupine.DataLength;
last: BOOLEAN;
[length, last] ← RPCLupine.Call[pkt, argLength, RPCLupine.maxDataLength, SignalDispatcher];
UNTIL last
DO IF receiverGapSecs > 0
THEN Process.Pause[Process.SecondsToTicks[receiverGapSecs]];
[length, last] ← RPCLupine.ReceiveExtraPkt[pkt];
ENDLOOP;
END;
END;
TestDispatcher: RPCLupine.Dispatcher =
BEGIN
-- Dummy dispatcher: consumes args and sends dummy result --
UNTIL lastPkt
DO IF receiverGapSecs > 0
THEN Process.Pause[Process.SecondsToTicks[receiverGapSecs]];
[callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt];
ENDLOOP;
Client[ ! RemoteSignal =>
BEGIN
RPCLupine.StartSignal[pkt];
[callLength,lastPkt] ← RPCLupine.Call[pkt, 0, RPCLupine.maxDataLength, NIL];
UNTIL lastPkt
DO [callLength,lastPkt] ← RPCLupine.ReceiveExtraPkt[pkt] ENDLOOP;
RESUME
END ];
IF callDelaySecs > 0
THEN Process.Pause[Process.SecondsToTicks[callDelaySecs]];
FOR res: CARDINAL IN [1..extraResPkts]
DO RPCLupine.SendPrelimPkt[pkt,extraResLength];
IF senderGapSecs > 0
THEN Process.Pause[Process.SecondsToTicks[senderGapSecs]];
ENDLOOP;
RETURN[resLength];
END;
-- ******** Test version of client code ******** --
Client: PROC = { IF raiseSignal THEN SIGNAL RemoteSignal[] };
-- remote procedure being called! --
instance: Rope.ROPEIF gvExport THEN gvInstance ELSE nongvInstance;
exported: BOOLEANFALSE;
expHandle: RPCLupine.ExportHandle;
Work: PROC =
BEGIN
import ← RPCLupine.ImportInterface[["RPC-Test", instance], [0,0] !
RPC.ImportFailed =>
IF why = unbound OR why = communications
THEN BEGIN
expHandle ← RPCLupine.ExportInterface[exporterName, exporterKey,
["RPC-Test", instance], TestDispatcher, [0,0]];
exported ← TRUE;
import ← RPCLupine.ImportInterface[["RPC-Test", instance],[0,0]];
CONTINUE
END ];
BEGIN
DO UNTIL userTest OR quit DO Process.Pause[Process.SecondsToTicks[5]] ENDLOOP;
IF quit THEN EXIT;
conversation ← IF authenticate
THEN RPC.StartConversation[callerName, callerKey, exporterName, CBCCheck]
ELSE RPC.unencrypted;
Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE];
Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE];
BEGIN
start: BasicTime.Pulses = BasicTime.GetClockPulses[];
end: BasicTime.Pulses;
minPulses: LONG CARDINALLAST[LONG CARDINAL];
elapsed: REAL;
minTime: LONG CARDINAL;
FOR call: CARDINAL IN [1..tries]
DO thisStart: BasicTime.Pulses;
thisPulses: LONG CARDINAL;
IF minWanted THEN thisStart ← BasicTime.GetClockPulses[];
Send[! RemoteSignal => IF resumeSignal THEN RESUME ELSE CONTINUE];
IF minWanted
THEN BEGIN
IF thisPulses < minPulses THEN minPulses ← thisPulses;
thisPulses ← BasicTime.GetClockPulses[] - thisStart;
END;
IF callGapSecs > 0
THEN Process.Pause[Process.SecondsToTicks[callGapSecs]];
ENDLOOP;
end ← BasicTime.GetClockPulses[];
elapsed ← BasicTime.PulsesToSeconds[end-start];
minTime ← BasicTime.PulsesToMicroseconds[minPulses];
IF authenticate THEN RPC.EndConversation[conversation];
IF signalFinished THEN SIGNAL Finished[];
END;
ENDLOOP;
END;
IF exported THEN [] ← RPCLupine.UnexportInterface[expHandle];
END;
caller ← FORK Work[];
END.