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; 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: BOOL_FALSE; GVGetAttribute: PUBLIC PROCEDURE [rName: ROPE, attribute: ATOM, default: ROPE] RETURNS [value: ROPE_NIL] = { reopening: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { 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: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RealNamesGV.GVUpdate[rName]; }; }; GVUpdateAll: PUBLIC PROCEDURE = { reopening: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RealNamesGV.GVUpdateAll[]; }; }; GVWait: PUBLIC PROCEDURE = { reopening: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RealNamesGV.GVWait[]; }; }; GVFlushCache: PUBLIC PROCEDURE = { reopening: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RealNamesGV.GVFlushCache[]; }; }; GVSaveCache: PUBLIC PROCEDURE = { reopening: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RealNamesGV.GVSaveCache[]; }; }; GVRestoreCache: PUBLIC PROCEDURE = { reopening: BOOL_FALSE; { 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: BOOL_FALSE; { ENABLE RPC.CallFailed => IF PostError[why] THEN RETRY ELSE CONTINUE; IF (~imported) AND (~PostError[$unbound]) THEN RETURN; RETURN[RealNamesGV.GVHostFromInstance[instance]]; }; }; 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: PROC[why: RPC.CallFailure] RETURNS [retry: BOOL_FALSE] = { 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]; }; }. ΨNamesGVClientImpl.mesa Copyright c 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. Global data Protected versions of NamesGV Procedures 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. PostError Κx˜™Icodešœ Οmœ1™Kš‘œ˜K˜—š Ÿœžœž œ žœ žœ žœ˜LKšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ(˜4Kš‘œ˜K˜—š Ÿœžœž œ žœ žœ˜BKš žœžœ‘ ž‘ž‘˜>šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kšžœ‘ œ%˜8Kš‘œ˜K˜—š Ÿœžœž œžœ žœ˜SKšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ+˜7Kš‘œ˜K˜—šŸœžœž œ žœ˜/Kš žœžœ‘ ž‘ž‘˜>šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kšžœ‘ œ˜+Kš‘œ˜K˜—š Ÿœžœž œ žœžœ˜FKšžœ)‘ ž‘ž‘˜Išž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kšžœ‘ œ˜/Kš‘œ˜K˜—šŸœžœž œ žœ˜1Kšžœ)‘ ž‘ž‘˜Išž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kšžœ‘ œ˜-Kš‘œ˜K˜—šŸœžœž œ žœ˜(Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ˜Kš‘œ˜K˜—šŸ œžœž ˜Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ˜Kš‘œ˜K˜—šŸœžœž ˜Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ ˜Kš‘œ˜K˜—šŸ œžœž ˜Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ˜Kš‘œ˜K˜—šŸ œžœž ˜Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ˜Kš‘œ˜K˜—šŸœžœž ˜ Kšœ‘ ž‘ž‘˜šž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kš‘ œ˜Kš‘œ˜K˜—šŸœžœž œžœ˜:Kšžœ6‘ ž‘ž‘˜Všž˜Kšž‘ž‘ž‘ž‘˜=—Kšž‘ž‘!˜6Kšž‘ œ˜1Kš‘œ˜K˜——K™™Kšœμžœ™ƒK™šŸœžœž œ˜#Kšœžœ˜!Kšœžœ#˜8K˜8K˜K˜Kšœ žœ˜Kšžœžœžœ ˜BKšžœ!˜%K˜Gšœ/˜/Jšœ?žœžœžœ˜`—K˜K˜—šŸœžœž œžœ˜/Kšœ žœ˜K˜ K˜—K˜—šœ ™ K˜š Ÿ œžœžœžœ žœžœ˜Ešžœ˜šžœ˜JšœžœQ˜fJšžœ˜ Jšœ˜—Jšžœ!žœ˜-J˜—šžœž˜šœ˜JšœžœQ˜f—šœ6˜6JšœF˜F—Jšœ žœ˜Jšžœžœ˜—Jšœ žœ˜Jšœ1˜1Jšœ žœ˜Jšžœžœ˜ K˜——Kšœ˜—…—²"