ThPartyToThPartySunRPC.mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Polle Zellweger (PTZ) October 29, 1990 4:00:19 pm PST
Pier, May 10, 1990 11:33:09 pm PDT
Swinehart, October 1, 1990 11:11 am PDT
Note: RegisterServiceInterface and LookupServiceInterface append "-Sun" to their type parameters, to promote PCedar/DCedar source sharing.
All action routines should be implemented as entry procedures protecting monitored records, but that would require redefining RPC.Conversation as a monitored record. We can do that once D-systems are dead.
Current fallback: monitor the error management procedures, and hope for the best.
If that doesn't work fallback: use a global monitor. This will sequentialize all party calls on the machine, but that's probably not much of a loss. DCS September 8, 1990 If problems arise, remember that we can easily enough require our clients, which are always "smartses", to serialize all calls on a per-shhh basis. DCS September 13, 1990 8:23:59 am PDT
DIRECTORY
BasicTime USING [ GMT ],
GVBasics USING [Password],
IV USING [KeyTableBody],
LoganBerry USING [ Attribute ],
Pup USING [ Address ],
RefID USING [ ID ],
Rope USING [ Concat ],
RPC USING [ InterfaceName, ShortROPE, VersionRange ],
SRPCCalls
USING [
Conversation, Error, GetSHandle, NewRPCConversation, ReleaseConversation, ReportProc, SHandle, TimeoutEnable ],
ThParty,
ThPartySunRPC,
ThPartySunRPControl,
ThPartySunRPCClient,
Thrush,
ThrushSunRPC,
ThrushSunRPCConvert
;
ThPartyToThPartySunRPC:
CEDAR
MONITOR
IMPORTS Rope, SRPCCalls, ThPartySunRPCClient, ThrushSunRPCConvert
EXPORTS ThParty, ThPartySunRPControl
~ {
OPEN ThrushSunRPCConvert;
Definitions
Attributes: TYPE = ThParty.Attributes;
Conversation: TYPE ~ SRPCCalls.Conversation;
ConversationInfo: TYPE = ThParty.ConversationInfo;
ConversationID: TYPE = Thrush.ConversationID;
PartyID: TYPE = Thrush.PartyID;
SmartsID:
TYPE = Thrush.SmartsID;
nullID: RefID.ID = Thrush.nullID;
Credentials: TYPE = Thrush.Credentials;
SRCredentials: TYPE = ThrushSunRPC.Credentials;
NB: TYPE = Thrush.NB;
ROPE: TYPE = Thrush.ROPE;
SHHH:
TYPE = Thrush.
SHHH;
none: SHHH = Thrush.none;
SHandle: TYPE ~ SRPCCalls.SHandle;
SmartsInterfaceName: TYPE = RPC.InterfaceName;
sunSHHH: INT = 0;
ThPartyHandle: TYPE ~ REF ThPartyHandleRec;
ThPartyHandleRec:
TYPE ~
RECORD [
rName: ROPE,
type: Thrush.PartyType,
interface: SmartsInterfaceName,
properties: ThParty.SmartsProperties,
reportState: ThPartySunRPControl.ReportState ←
NIL,
connected: connection exists and is healthy; enabled: autoConnect is still in effect.
reportProblem: ThPartySunRPControl.ReportProblem ←
NIL,
Both reportState and reportProblem are optional ways to report events to a common site.
If reportProblem is not supplied and a problem is discovered, it will be reported only through nb error code returns.
reportData: REF ← NIL, -- supplied by client, returned in reports.
Derived values
registered: BOOL ← FALSE, -- implies sHandle.connected; also registered with Thrush.
sHandle: SHandle,
partyID: Thrush.PartyID← nullID,
smartsID: Thrush.SmartsID← nullID
];
RetryAfterReconnect: ERROR = CODE;
recentShhh: SHHH ← NIL;
Conversation Management
CreateConversation:
PUBLIC
PROC [shhh:
SHHH ← none, credentials: Credentials,
state: Thrush.StateInConv←$initiating, reason: Thrush.Reason ←
NIL,
comment:
ROPE ←
NIL, convAttributes: Attributes←
NIL, partyAttributes: Attributes←
NIL,
checkConflict:
BOOL ←
FALSE]
RETURNS [ nb:
NB, convEvent: Thrush.ConvEvent ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srConvEvent: ThrushSunRPC.ConvEvent;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
[srNB, srConvEvent] ← ThPartySunRPCClient.CreateConversation[pHandle.sHandle.handle, sunSHHH, srCredentials, StateToSr[state], ATOMToSr[reason], ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes], checkConflict ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
convEvent ← SrToConvEvent[srConvEvent];
};
Alert:
PUBLIC
PROC [shhh:
SHHH ← none, credentials: Credentials, calledPartyID: PartyID←nullID, comment:
ROPE←
NIL, convAttributes: Attributes←
NIL, partyAttributes: Attributes←
NIL]
RETURNS [nb:
NB ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
[srNB] ← ThPartySunRPCClient.Alert[pHandle.sHandle.handle, sunSHHH, srCredentials, calledPartyID, ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Advance:
PUBLIC
PROC [shhh:
SHHH ← none, credentials: Credentials, state: Thrush.StateInConv, reportToAll:
BOOL←
FALSE, reason: Thrush.Reason←
NIL, comment:
ROPE←
NIL, convAttributes: Attributes←
NIL, partyAttributes: Attributes←
NIL,bilateral:
BOOL ←
FALSE, checkConflict:
BOOL ←
FALSE ]
RETURNS [nb:
NB, convEvent: Thrush.ConvEvent ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srConvEvent: ThrushSunRPC.ConvEvent;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
[srNB, srConvEvent] ← ThPartySunRPCClient.Advance[pHandle.sHandle.handle, sunSHHH, srCredentials, StateToSr[state], reportToAll, ATOMToSr[reason], ROPEToSr[comment], AttributesToSr[convAttributes], AttributesToSr[partyAttributes], bilateral, checkConflict ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
convEvent ← SrToConvEvent[srConvEvent];
};
ReportAction:
PUBLIC
PROC [shhh:
SHHH ← none, report: Thrush.ActionReport,
reportToAll:
BOOL ←
FALSE, selfOnCompletion:
BOOL←
FALSE ]
RETURNS [nb:
NB, numReportsIssued:
NAT𡤀] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, report.other]; -- This is where caller puts its credentials!
report.other ← SrToCredentials[srCredentials];
[srNB, numReportsIssued] ← ThPartySunRPCClient.ReportAction[pHandle.sHandle.handle, sunSHHH, ActionReportToSr[report], reportToAll, selfOnCompletion ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Enumerations, registrations, queries
GetConversationInfo:
PUBLIC
PROC [ shh:
SHHH←none, convID: ConversationID ]
RETURNS [nb:
NB, cInfo: ConversationInfo] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srCInfo: ThPartySunRPC.ConversationInfo;
pHandle: ThPartyHandle ← GetInfo[shh].pHandle;
[srNB, srCInfo] ← ThPartySunRPCClient.GetConversationInfo[pHandle.sHandle.handle, sunSHHH, ConvIDToSr[convID] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
cInfo ← SrToConversationInfo[srCInfo];
};
Named conversations
RegisterConversation:
PUBLIC
PROC [ shhh:
SHHH ← none, credentials: Credentials, name:
ROPE, convType: ThParty.ConvType ← $meeting, convAttributes: Attributes ←
NIL, accessList: ThParty.AccessList ←
NIL ]
RETURNS [ nb:
NB ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
[srNB] ← ThPartySunRPCClient.
RegisterConversation[pHandle.sHandle.handle, sunSHHH,
srCredentials, ROPEToSr[name], ConvTypeToSr[convType], AttributesToSr[convAttributes], AccessListToSr[accessList] ];
Rope.InlineFlatten the rope??
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
GetConversationFromName:
PUBLIC
PROC [ shhh:
SHHH ← none, partyID: PartyID, name:
ROPE ]
RETURNS [ nb:
NB, cInfo: ConversationInfo ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srCInfo: ThPartySunRPC.ConversationInfo;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh];
partyID ← srCredentials.partyID;
[srNB, srCInfo] ← ThPartySunRPCClient.GetConversationFromName[pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[name] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
cInfo ← SrToConversationInfo[srCInfo];
};
EnumerateNamedConversations:
PUBLIC
PROC [ shhh:
SHHH ← none, partyID: PartyID ]
RETURNS [ nb:
NB, candidates:
LIST
OF ConversationInfo ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srCandidates: ThPartySunRPC.CandidateList;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh];
partyID ← srCredentials.partyID;
[srNB, srCandidates] ← ThPartySunRPCClient.EnumerateNamedConversations[ pHandle.sHandle.handle, sunSHHH, partyID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
candidates ← SrToCandidateList[srCandidates];
};
Party information
GetPartyInfo:
PUBLIC
PROC [ shh:
SHHH←none, credentials: Credentials, nameReq: ThParty.NameReq←$current, allParties:
BOOL←
FALSE ]
RETURNS [ nb:
NB, pInfo: ThParty.PartyInfo ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srPInfo: ThPartySunRPC.PartyInfo;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh, credentials];
[srNB, srPInfo] ← ThPartySunRPCClient.GetPartyInfo[pHandle.sHandle.handle, sunSHHH, srCredentials, ATOMToSr[nameReq], allParties ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
pInfo ← SrToPartyInfo[srPInfo];
};
DescribeParty:
PUBLIC
PROC[ partyID: Thrush.PartyID, nameReq: ThParty.NameReq ]
RETURNS [ nb:
NB, description: Thrush.
ROPE, type: Thrush.PartyType,
partner: Thrush.PartyID←nullID, visitee: Thrush.PartyID←nullID,
visitors: LIST OF Thrush.PartyID←NIL ] ~ {
shhh: SHHH ← recentShhh;
{
Use a remembered one; can sometimes slow performance of other instances.
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srType: ThrushSunRPC.PartyType;
srVisitors: ThPartySunRPC.VisitorList;
pHandle: ThPartyHandle;
pHandle ← GetInfo[shhh].pHandle;
[srNB, description, srType, partner, visitee, srVisitors] ← ThPartySunRPCClient.DescribeParty[pHandle.sHandle.handle, --sunSHHH,-- partyID, ATOMToSr[nameReq] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
type ← SrToATOM[srType];
visitors ← SrToVisitorList[srVisitors];
description ← SrToROPE[description];
}; };
AddAttributes:
PUBLIC
PROC[ credentials: Credentials, convAttributes: Attributes←
NIL, partyAttributes: Attributes←
NIL ]
RETURNS [nb:
NB] ~ {
shhh: SHHH ← recentShhh;
{
Use a remembered one; can sometimes slow performance of other instances.
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
srNB ← ThPartySunRPCClient.AddAttributes[pHandle.sHandle.handle, --sunSHHH, -- srCredentials, AttributesToSr[convAttributes], AttributesToSr[partyAttributes] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
}; };
Service action registration, lookup. See also ReportAction, above.
RegisterServiceInterface:
PUBLIC
PROC[ shhh:
SHHH ← none, credentials: Credentials, interfaceSpecPattern: Thrush.InterfaceSpec ]
RETURNS [nb:
NB, interfaceSpec: Thrush.InterfaceSpec] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srInterfaceSpec: ThrushSunRPC.InterfaceSpec;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
interfaceSpecPattern.interfaceName.type ← Rope.Concat[interfaceSpecPattern.interfaceName.type, "-Sun"];
[srNB, srInterfaceSpec] ← ThPartySunRPCClient.RegisterServiceInterface[ pHandle.sHandle.handle, sunSHHH, srCredentials, InterfaceSpecToSr[interfaceSpecPattern] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
interfaceSpec ← SrToInterfaceSpec[srInterfaceSpec];
};
LookupServiceInterface:
PUBLIC
PROC[ shhh:
SHHH ← none, credentials: Credentials,
serviceParty: PartyID, type:
RPC.ShortROPE ]
RETURNS [nb:
NB, interfaceSpec: Thrush.InterfaceSpec] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srInterfaceSpec: ThrushSunRPC.InterfaceSpec;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh, credentials];
[srNB, srInterfaceSpec] ← ThPartySunRPCClient.LookupServiceInterface[ pHandle.sHandle.handle, sunSHHH, srCredentials, serviceParty, Rope.Concat[type, "-Sun"] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
interfaceSpec ← SrToInterfaceSpec[srInterfaceSpec];
};
Encryption key registration.
RegisterKey:
PUBLIC
PROC[ shh:
SHHH ← none, credentials: Credentials, key: Thrush.EncryptionKey, reportNewKeys:
BOOL←
FALSE ]
RETURNS [ nb:
NB, keyIndex: [0..17B] ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh, credentials];
[srNB, keyIndex] ← ThPartySunRPCClient.RegisterKey[ pHandle.sHandle.handle, sunSHHH, srCredentials, EncryptionKeyToSr[key], reportNewKeys ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
GetKeyTable:
PUBLIC
PROC [ shh:
SHHH←none, credentials: Credentials ]
RETURNS [ nb:
NB, keyTable: Thrush.KeyTable ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
srKeyTable: ThrushSunRPC.KeyTable;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh, credentials];
[srNB, srKeyTable] ← ThPartySunRPCClient.GetKeyTable[ pHandle.sHandle.handle, sunSHHH, srCredentials ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
keyTable ← SrToKeyTable[srKeyTable];
};
UnregisterKey:
PUBLIC
PROC[ shh:
SHHH ← none, credentials: Credentials, key: Thrush.EncryptionKey ]
RETURNS [ nb:
NB ] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh, credentials];
srNB ← ThPartySunRPCClient.UnregisterKey[ pHandle.sHandle.handle, sunSHHH, srCredentials, EncryptionKeyToSr[key] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Names to Parties, Numbers to Parties
GetParty:
PUBLIC
PROC[ shh:
SHHH←none, partyID: PartyID, rName:
ROPE←
NIL, type: Thrush.PartyType←
NIL ]
RETURNS [nb:
NB, newPartyID: PartyID] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
partyID ← srCredentials.partyID; -- This is the right partyID to use.
[srNB, newPartyID] ← ThPartySunRPCClient.GetParty[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[rName], ATOMToSr[type] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
GetPartyFromNumber:
PUBLIC
PROC[ shh:
SHHH←none, partyID: PartyID, phoneNumber: Thrush.
ROPE←
NIL, description:
ROPE←
NIL ]
RETURNS [nb:
NB, newPartyID: PartyID] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
partyID ← srCredentials.partyID; -- This is the right partyID to use.
[srNB, newPartyID] ← ThPartySunRPCClient.GetPartyFromNumber[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[phoneNumber], ROPEToSr[description] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
GetPartyFromFeepNum:
PUBLIC
PROC[ shh:
SHHH←none, partyID: PartyID, feepNum: Thrush.
ROPE←
NIL ]
RETURNS [nb:
NB, newPartyID: PartyID] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
partyID ← srCredentials.partyID; -- This is the right partyID to use.
[srNB, newPartyID] ← ThPartySunRPCClient.GetPartyFromFeepNum[ pHandle.sHandle.handle, sunSHHH, partyID, ROPEToSr[feepNum] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
GetCurrentParty:
PUBLIC
PROC[shh:
SHHH←none, smartsID: SmartsID]
RETURNS [nb:
NB, partyID: Thrush.PartyID] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
smartsID ← srCredentials.smartsID;
[srNB, partyID] ← ThPartySunRPCClient.GetCurrentParty[pHandle.sHandle.handle, sunSHHH, smartsID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
ReleaseParty:
PUBLIC
PROC[shh:
SHHH←none, partyID: PartyID, targetPartyID: PartyID]
RETURNS [nb:
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
partyID ← srCredentials.partyID; -- This is the right partyID to use.
srNB ← ThPartySunRPCClient.ReleaseParty[ pHandle.sHandle.handle, sunSHHH, partyID, targetPartyID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Information about people and parties
GetNumbersForRName:
PUBLIC
PROC[shh:
SHHH←none, rName:
ROPE]
RETURNS [fullRName:
ROPE, number:
ROPE, homeNumber:
ROPE] ~ {
ENABLE {
SRPCCalls.Error => { [] ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
pHandle: ThPartyHandle;
pHandle ← GetInfo[shhh: shh, rereg: FALSE].pHandle;
[fullRName, number, homeNumber] ← ThPartySunRPCClient.GetNumbersForRName[ pHandle.sHandle.handle, sunSHHH, ROPEToSr[rName] ];
ReRegisterOnFailure[pHandle, $success]; -- Call won't fail here due to no registration
RETURN[fullRName: SrToROPE[fullRName], number: SrToROPE[number],
homeNumber: SrToROPE[homeNumber] ];
};
Party and Smarts creation, initialization
Register:
PUBLIC
PROC[ shh:
SHHH←none, rName:
ROPE←
NIL, type: Thrush.PartyType← $individual, clonePartyID: PartyID ← nullID, interface: SmartsInterfaceName, properties: ThParty.SmartsProperties ]
RETURNS [ nb:
NB, credentials: Credentials ] ~ {
ERROR; -- Shouldn't call this directly!
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
pHandle ← GetInfo[shh].pHandle;
[srNB, srCredentials] ← ThPartySunRPCClient.Register[ pHandle.sHandle.handle, sunSHHH, rName, ATOMToSr[type], clonePartyID, InterfaceNameToSr[interface], SmartsPropertiesToSr[properties] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
credentials ← SrToCredentials[srCredentials];
};
CheckIn:
PUBLIC
PROC[shh:
SHHH←none, credentials: Credentials]
RETURNS [nb:
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh, credentials];
srNB ← ThPartySunRPCClient.CheckIn[ pHandle.sHandle.handle, sunSHHH, srCredentials ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Deregister:
PUBLIC
PROC[shh:
SHHH←none, smartsID: SmartsID]
RETURNS [nb:
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shhh: shh, rereg: FALSE];
smartsID ← srCredentials.smartsID;
srNB ← ThPartySunRPCClient.Deregister[ pHandle.sHandle.handle, sunSHHH, smartsID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Enable:
PUBLIC
PROC[shh:
SHHH←none, smartsID: SmartsID]
RETURNS [nb: Thrush.
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
smartsID ← srCredentials.smartsID;
srNB ← ThPartySunRPCClient.Enable[ pHandle.sHandle.handle, sunSHHH, smartsID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Disable:
PUBLIC
PROC[shh:
SHHH←none, smartsID: SmartsID]
RETURNS [nb: Thrush.
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
smartsID ← srCredentials.smartsID;
srNB ← ThPartySunRPCClient.Disable[ pHandle.sHandle.handle, sunSHHH, smartsID ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Visit:
PUBLIC
PROC[ shh:
SHHH←none, hostPartyID: PartyID, guestPartyID: PartyID,
guestPassword: GVBasics.Password ]
RETURNS [nb: Thrush.
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
hostPartyID ← srCredentials.partyID;
srNB ← ThPartySunRPCClient.Visit[ pHandle.sHandle.handle, sunSHHH, hostPartyID, guestPartyID, PasswordToSr[guestPassword] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Unvisit:
PUBLIC
PROC[ shh:
SHHH←none, hostPartyID: PartyID, guestPartyID: PartyID,
guestPassword: GVBasics.Password ]
RETURNS [nb: Thrush.
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
hostPartyID ← srCredentials.partyID;
srNB ← ThPartySunRPCClient.Unvisit[ pHandle.sHandle.handle, sunSHHH, hostPartyID, guestPartyID, PasswordToSr[guestPassword] ];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
UnvisitSelf:
PUBLIC
PROC[ shh:
SHHH←none, guestPartyID: PartyID ]
RETURNS [nb: Thrush.
NB] ~ {
ENABLE {
SRPCCalls.Error => { nb ← ReportError[shh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => RETRY;
UNWIND => NULL;
};
srNB: ThrushSunRPC.NB;
pHandle: ThPartyHandle; srCredentials: SRCredentials;
[pHandle, srCredentials] ← GetInfo[shh];
guestPartyID ← srCredentials.partyID;
srNB ← ThPartySunRPCClient.UnvisitSelf[ pHandle.sHandle.handle, sunSHHH, guestPartyID];
nb ← SrToATOM[srNB];
ReRegisterOnFailure[pHandle, nb];
};
Connecting
sunPgm: CARD ← 390909; -- decimal program number for ThParty
sunPgmVersion: CARD ← 1;
sunCallTimeout: INT ← 3000;
sunCallRetries: INT ← 3;
sunCallTimeoutEnable: SRPCCalls.TimeoutEnable ← always;
If this procedure fails to import, it reports the failure as Report or Problem, and indicates the resulting connection state via the reportState routine. It will return a shhh value in any case, since that will be needed in order to retry later.
ThrushConnect:
PUBLIC
PROC [
server: ROPE, rName: ROPE, type: Thrush.PartyType,
interface: SmartsInterfaceName, properties: ThParty.SmartsProperties,
reportState: ThPartySunRPControl.ReportState, reportProblem: ThPartySunRPControl.ReportProblem←NIL, reportData: REF←NIL]
RETURNS [shhh: SHHH ← none] ~ {
Worry about what happens when interface is already imported. Perhaps not idempotent yet. Worry about how to unregister (Unfinch.) Consider a lookup that identifies already-imported interfaces? Consider a version of this that takes an existing, unregistered, pHandle as an argument!
sHandle: SHandle;
pHandle: ThPartyHandle;
shhh ← SRPCCalls.NewRPCConversation[
serverName: server, rpcProgram: sunPgm, rpcVersion: sunPgmVersion, timeoutEnable: sunCallTimeoutEnable, timeoutInMs: sunCallTimeout, retries: sunCallRetries, reportProc: ReportNonfatalRPCError];
sHandle ← SRPCCalls.GetSHandle[shhh];
pHandle ← NEW[ThPartyHandleRec ← [rName: rName, type: type, interface: interface, properties: properties, sHandle: sHandle, reportState: reportState, reportProblem: reportProblem, reportData: reportData]];
sHandle.clientData ← pHandle;
sHandle.enabled ← TRUE; -- Unilaterally assert a will to connect.
{
ENABLE {
SRPCCalls.Error => { []←ReportError[shhh, errCode, explanation]; CONTINUE; };
RetryAfterReconnect => CONTINUE; -- Successful completion of very strange procedure.
};
Register with Thrush
ReRegisterOnFailure[pHandle, $unbound];
};
};
ThrushDisconnect:
PUBLIC
PROC [shhh: Thrush.
SHHH, disable:
BOOL←
TRUE] ~ {
ENABLE {
SRPCCalls.Error => { []←ReportError[shhh, errCode, explanation]; CONTINUE; };
UNWIND => NULL;
};
pHandle: ThPartyHandle ← GetInfo[shhh: shhh, rereg: FALSE].pHandle;
wasRegistered: BOOL ← pHandle.registered;
pHandle.registered ← FALSE; -- even if it fails!
IF disable THEN pHandle.sHandle.enabled ← FALSE;
IF wasRegistered THEN [] ← Deregister[shhh, pHandle.smartsID];
[] ← ReportError[shhh, $disconnected, "Disconnected from server"];
};
ThrushReportState:
PUBLIC
PROC [shhh: Thrush.
SHHH, enabled:
BOOL, connected:
BOOL] ~ {
ENABLE {
SRPCCalls.Error => { []←ReportError[shhh, errCode, explanation]; CONTINUE; };
UNWIND => NULL;
};
pHandle: ThPartyHandle ← GetInfo[shhh: shhh, rereg: FALSE].pHandle;
IF ~enabled THEN pHandle.sHandle.enabled ← FALSE;
pHandle.registered ← connected;
};
ReleaseConversation:
PUBLIC
PROC [shhh: Thrush.
SHHH] ~ {
ENABLE {
SRPCCalls.Error => { []←ReportError[shhh, errCode, explanation]; CONTINUE; };
UNWIND => NULL;
};
SRPCCalls.ReleaseConversation[shhh]; -- Thrush already assumed disconnected, for now.
};
GetInfo:
ENTRY
PROC[shhh: Conversation, credentials: Credentials←[], rereg:
BOOL←
TRUE]
RETURNS [pHandle: ThPartyHandle, updatedCredentials: SRCredentials] ~ {
Entry holds others out during error recovery.
ENABLE UNWIND => NULL; -- !!!!!!!!!!! DCS September 14, 1990 3:43:51 pm PDT
sHandle: SHandle;
IF shhh = NIL THEN SRPCCalls.Error[$noConversationSupplied];
sHandle ← SRPCCalls.GetSHandle[shhh];
IF sHandle=NIL THEN SRPCCalls.Error[$invalidConversationSupplied];
pHandle ← NARROW[sHandle.clientData];
IF pHandle = NIL THEN SRPCCalls.Error[$invalidConversationSupplied];
recentShhh ← shhh; -- Any port in a storm; see usage for explanation.
IF ~pHandle.registered AND rereg THEN RROFInt[pHandle, $unbound];
credentials.partyID ← pHandle.partyID;
credentials.smartsID ← pHandle.smartsID;
updatedCredentials ← ThrushSunRPCConvert.CredentialsToSr[credentials];
};
ReportNonfatalRPCError: SRPCCalls.ReportProc ~ {
IF sHandle#
NIL
AND sHandle.conversation#
NIL
THEN
[]←ReportError[sHandle.conversation, ec, expl];
};
ReportError:
PROC[shhh:
SHHH, ec:
ATOM, expl:
ROPE]
RETURNS [nb:
NB] ~ {
pHandle: ThPartyHandle ← NARROW[SRPCCalls.GetSHandle[shhh].clientData];
IF pHandle.reportProblem#
NIL
THEN pHandle.reportProblem[pHandle.reportData, ec, expl];
Else the error is not at present reported at all. Could use some default Feedback call.
ReportState[pHandle];
nb ← $callFailed;
};
ReRegisterOnFailure:
ENTRY PROC[pHandle: ThPartyHandle, nb:
NB] ~ {
Fatal errors at this level will be caught and reported by the caller!
When successful, this procedure raises RetryAfterReconnect, in order to permit its caller to retry the entire procedure. (Turns each of the callers into a kind of LOOP).
Entry here should be enough to eliminate most important reentrancy problems? If there's an entry here, we can't call GetInfo or allow ReRegisterOnFailure to be recursively entered.
ENABLE UNWIND => NULL;
RROFInt[pHandle, nb];
};
RROFInt:
INTERNAL
PROC[pHandle: ThPartyHandle, nb:
NB] ~ {
Fatal errors at this level will be caught and reported by the caller!
When successful, this procedure raises RetryAfterReconnect, in order to permit its caller to retry the entire procedure. (Turns each of the callers into a kind of LOOP).
Entry here should be enough to eliminate most important reentrancy problems? If there's an entry here, we can't call GetInfo or allow ReRegisterOnFailure to be recursively entered.
credentials: Credentials;
srNB: ThrushSunRPC.NB;
srCredentials: SRCredentials;
SELECT nb
FROM
$noSuchParty, $noSuchSmarts, $unbound => NULL;
ENDCASE => RETURN; -- $success, or some error that implies the connection is still around.
pHandle.registered ← FALSE;
IF ~pHandle.sHandle.enabled THEN RETURN;
[srNB, srCredentials] ← ThPartySunRPCClient.Register[ h: pHandle.sHandle.handle, shh: sunSHHH, rName: ROPEToSr[pHandle.rName], type: ATOMToSr[pHandle.type], interface: InterfaceNameToSr[pHandle.interface], properties: SmartsPropertiesToSr[pHandle.properties], clonePartyID: nullID ];
nb ← SrToATOM[srNB];
credentials ← SrToCredentials[srCredentials];
IF nb=$success
THEN {
srNB ←
ThPartySunRPCClient.Enable[ pHandle.sHandle.handle, sunSHHH, credentials.smartsID ];
nb ← SrToATOM[srNB]; };
IF nb=$success
THEN {
[srNB, credentials.partyID] ← ThPartySunRPCClient.GetCurrentParty[
h: pHandle.sHandle.handle, shh: sunSHHH, smartsID: credentials.smartsID];
nb ← SrToATOM[srNB]; };
IF nb#$success
THEN {
nb ← ReportError[pHandle.sHandle.conversation, nb, "Can't register with server"]; RETURN; };
pHandle.registered ← TRUE;
pHandle.partyID ← credentials.partyID;
pHandle.smartsID ← credentials.smartsID;
ReportState[pHandle];
ERROR RetryAfterReconnect; -- really success.
};
ReportState:
PROC[pHandle: ThPartyHandle] ~ {
Notify any interested parties about current connection state.
IF NOT pHandle.sHandle.connected THEN pHandle.registered ← FALSE;
IF pHandle.reportState#
NIL
THEN
pHandle.reportState[
pHandle.reportData, pHandle.registered, pHandle.sHandle.connected, pHandle.sHandle.enabled,
pHandle.partyID, pHandle.smartsID];
};
}.
Polle Zellweger (PTZ) October 1, 1989 5:03:15 pm PDT
changes to: ThPartyToThPartySunRPC, CreateConversation, Alert, SrToCredentials, }
Polle Zellweger (PTZ) October 3, 1989 12:54:30 pm PDT
changes to: ThPartyToThPartySunRPC, CreateConversation, Alert, SrToAttributes, AttributesToSr, SrToCredentials, SrToConvEvent, ConvEventToSr, Advance, ReportAction, SrToActionReport, ActionReportToSr
Polle Zellweger (PTZ) March 16, 1990 6:14:47 pm PST
changes to: ReportAction
Polle Zellweger (PTZ) March 21, 1990 11:09:01 pm PST
changes to: ThPartyToThPartySunRPC, GetConversationInfo, SrToConversationInfo, SrToAddress, SrToCredentials, thPartyInfo, GetInfo
Polle Zellweger (PTZ) April 19, 1990 12:57:36 pm PDT
changes to: ThPartyToThPartySunRPC, SrToAddress, }
Polle Zellweger (PTZ) May 2, 1990 9:43:19 pm PDT
changes to: DIRECTORY, ThPartyToThPartySunRPC, SmartsInterfaceRecord, sunSHHH, ThPartyInfo, ThPartyRecord, thinfo, GetInfo, FinchRegister, SrToConversationInfo
Polle Zellweger (PTZ) May 4, 1990 4:53:29 pm PDT
changes to: SrToKeyTable, KeyTableToSr, GetKeyTable, UnregisterKey, GetParty, GetPartyFromNumber, GetPartyFromFeepNum, GetCurrentParty, ReleaseParty, GetNumbersForRName, Visit, Unvisit
Polle Zellweger (PTZ) May 8, 1990 4:50:33 pm PDT
changes to: SrToAttributes, SmartsPropertiesToSr, SrToVisitorList, ReleaseParty, Register, CheckIn, Deregister, Enable, Disable, Visit, Unvisit, UnvisitSelf, DIRECTORY, SmartsInterfaceName, RegisterConversation, EnumerateNamedConversations, GetPartyInfo, SrToPartyInfo, PartySeq, SrToPartyList, DescribeParty, AddAttributes, GetKeyTable, UnregisterKey, SrToCandidateList, CredentialsToSr, SrToInterfaceSpec, SrToKeyTable, KeyTableToSr, SrToVersionRange, VersionRangeToSr, SrToSmartsInterface, SmartsInterfaceToSr, CreateConversation, Advance, GetConversationInfo, SrToConvEvent, ConvEventToSr, SrToConversationInfo, SrToConvID, ConvIDToSr, SrToConvType, ConvTypeToSr, SrToCredentials, SrToEncryptionKey, EncryptionKeyToSr, SrToGMT, GMTToSr, InterfaceSpecToSr, SrToPartyInfoSpec, PasswordToSr, SrToState, StateToSr
Pier, May 10, 1990 11:33:09 am PDT
moved data conversion routines to ThrushSunRPCConvert
Polle Zellweger (PTZ) May 11, 1990 4:08:39 pm PDT
Atom.GetPName couldn't handle NIL, so make a new conversion routine.
Polle Zellweger (PTZ) July 24, 1990 7:28:23 pm PDT
SunYPAgent.Match has different # params in DCedar & PCedar
changes to: SunYPNameToAddress
Polle Zellweger (PTZ) August 1, 1990 6:39:57 pm PDT
Keep multiple handles for multiple callers. NOTE: 2 ThParty calls have no SHHH param!!!
changes to: ImportInterface, GetInfo & all procs GetInfo[] -> GetInfo[shh or shhh]
Polle Zellweger (PTZ) August 14, 1990 9:22:53 am PDT
Append "-Sun" to calls to (Register|Lookup)ServiceInterface (promotes PCedar/DCedar source sharing).
changes to: DIRECTORY, LookupServiceInterface, RegisterServiceInterface
Swinehart, August 30, 1990 6:36:07 pm PDT
Add robust failure management code. Primary concerns: invalid initial server specifications, response to timeouts due to server or network failures.
Polle Zellweger (PTZ) October 29, 1990 3:58:11 pm PST
Allow detection of NIL ropes across a SunRPC connection.
changes to: CreateConversation, Alert, Advance, RegisterConversation, GetConversationFromName, DescribeParty, GetParty, GetPartyFromNumber, GetPartyFromFeepNum, GetNumbersForRName, RROFInt