NamesGVClientImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Swinehart, June 27, 1986 10:39:12 am PDT
Automatic connection management for NamesGVRpcClientImpl.mesa
This is something Lupine could generate automatically. Better still, StartCall could include these capabilities. In that case, failures would have to be reported through errors, probably.
DIRECTORY
IO,
NamesGV,
NamesGVRpcControl,
Pup USING [ nullSocket ],
Rope USING [ ROPE ],
RPC,
RPCLupine,
RPCLupineExtras,
UserProfile USING [ Token ],
VoiceUtils USING [ NetAddress, NetAddressFromRope, nullNetAddress, Problem ]
;
NamesGVClientImpl: CEDAR PROGRAM
IMPORTS IO, RealControl: NamesGVRpcControl, RealNamesGV: NamesGV, RPC, UserProfile, VoiceUtils
EXPORTS NamesGV, NamesGVRpcControl = {
OPEN IO, NamesGV;
Global data
gvInterfaceName: RealControl.InterfaceName ← [
type: "NamesGV.Lark",
instance: UserProfile.Token[key: "NamesGVInstance", default: "Strowger.Lark"]];
importHostHint: VoiceUtils.NetAddress ← [[173B],[270B], Pup.nullSocket]; -- Growler is default!
imported: BOOLFALSE;
Protected versions of NamesGV Procedures
GVGetAttribute: PUBLIC PROCEDURE [rName: ROPE, attribute: ATOM, default: ROPE]
RETURNS [value: ROPENIL] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVGetAttribute[rName, attribute, default]];
}; };
GVSetAttribute: PUBLIC PROCEDURE [rName: ROPE, attribute: ATOM, value: ROPE]
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVSetAttribute[rName, attribute, value];
}; };
GVGetAttributeSeq: PUBLIC PROCEDURE [rName: ROPE, attribute: ATOM]
RETURNS [value: AttributeSeq←NIL] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVGetAttributeSeq[rName, attribute]];
}; };
GVSetAttributeSeq:PUBLIC PROCEDURE[rName:ROPE, attribute:ATOM, value: AttributeSeq]
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVSetAttributeSeq[rName, attribute, value];
}; };
GVGetAttributes: PUBLIC PROCEDURE [rName: ROPE]
RETURNS [value: AttributeSeq←NIL] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVGetAttributes[rName]];
}; };
GVAuthenticate: PUBLIC PROCEDURE [rName: ROPE, key: RPC.EncryptionKey]
RETURNS [authenticity: Authenticity←unknown] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVAuthenticate[rName, key]];
}; };
GVIsAuthenticated: PUBLIC PROCEDURE [rName: ROPE]
RETURNS [authenticity: Authenticity←unknown] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVIsAuthenticated[rName]];
}; };
GVUpdate: PUBLIC PROCEDURE [rName: ROPE]
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVUpdate[rName];
}; };
GVUpdateAll: PUBLIC PROCEDURE
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVUpdateAll[];
}; };
GVWait: PUBLIC PROCEDURE
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVWait[];
}; };
GVFlushCache: PUBLIC PROCEDURE
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVFlushCache[];
}; };
GVSaveCache: PUBLIC PROCEDURE
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVSaveCache[];
}; };
GVRestoreCache: PUBLIC PROCEDURE
= { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RealNamesGV.GVRestoreCache[];
}; };
GVHostFromInstance: PUBLIC PROCEDURE [instance: Rope.ROPE]
RETURNS [VoiceUtils.NetAddress←VoiceUtils.nullNetAddress] = { reopening: BOOLFALSE; {
ENABLE
RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE;
IF (~imported) AND (~PostError[$unbound]) THEN RETURN;
RETURN[RealNamesGV.GVHostFromInstance[instance]];
}; };
Import/Unimport
We don't intercept errors here, in case clients want to be careful during initial importing. Later, we do intercept them, catch them, and render them relatively harmless. Probably ought to be a registered error routine instead, or an ERROR originating here.
ImportInterface: PUBLIC PROCEDURE [
interfaceName: RPC.InterfaceName,
parameterStorage: RPC.Zones ← RealControl.standardZones,
hostHint: RPCLupineExtras.RPCHost←RPCLupineExtras.noHost
] = {
hostHint ← importHostHint;
imported ← FALSE;
IF interfaceName.instance=NIL THEN interfaceName ← gvInterfaceName
ELSE gvInterfaceName ← interfaceName;
RealControl.ImportInterface[interfaceName, parameterStorage, hostHint];
importHostHint ← VoiceUtils.NetAddressFromRope[
RealNamesGV.GVGetAttribute[gvInterfaceName.instance, $connect, NIL!RPC.CallFailed => CONTINUE]];
};
UnimportInterface: PUBLIC PROCEDURE = TRUSTED {
imported ← FALSE;
RealControl.UnimportInterface[];
};
PostError
PostError: PROC[why: RPC.CallFailure] RETURNS [retry: BOOLFALSE] = {
ENABLE {
RPC.ImportFailed => {
VoiceUtils.Problem[IO.PutFR["Could not import NamesGV (%g)", rope[gvInterfaceName.instance]], $Finch];
CONTINUE;
};
RPC.CallFailed => { why ← $timeout; RETRY; };
};
SELECT why FROM
$timeout, $busy =>
VoiceUtils.Problem[IO.PutFR["No response from NamesGV (%g)", rope[gvInterfaceName.instance]], $Finch];
$runtimeProtocol, $stubProtocol => VoiceUtils.Problem[
"Protocol violation in communications with NamesGV database", $Finch];
$unbound => NULL;
ENDCASE=>ERROR;
imported ← FALSE;
ImportInterface [interfaceName: gvInterfaceName];
imported ← TRUE;
RETURN[TRUE];
};
}.