SunRPCNotes.tioga
Polle Zellweger (PTZ) May 16, 1990 6:17:36 pm PDT
Swinehart, September 17, 1990 4:01:29 pm PDT
Date: 29 Sep 89 08:53:26 PDT (Friday)
From: juhlig.PA
Subject: Re: SunRPC numbers
In-reply-to: PolleZ's message of Thu, 28 Sep 89 18:33:55 PDT
To: PolleZ
cc: SunSupport^, Swinehart, Terry
Polle,
The numbers you requested have been assigned and are as follows:
390908 Thrush
390909 ThParty
390910 ThSmarts
390911 SynthesizerServer
390912 VoiceRopeServer
390913 LarkTTY
390914 LarkFeep
sunsupport
ThParty ->
ThPartyIRImpl ->
ThPartyToThPartySunRPC(conversion to/from wire types, add SunRPC handle) ->
ThPartySunRPC(types only) ->
ThPartySunRPCClientStub(generated by Sirocco & hand-edited)
==>>
ThPartySunRPCServerStub(edited from ThPartyPxxVy) ->
ThPartySunRPC(types only) ->
ThPartySunRPCToThParty(conversion to/from wire types, remove SunRPC handle) ->
ThParty -> ThPartyImpl
zSunRPC.mesa -- copy of zPxVy.mesa with the procedure declarations removed (i.e. just the type declarations)
zSunRPCClient.mesa -- copy of zPxVy.mesa with only the procedure declarations
zSunRPCServer.mesa -- identical to zSunRPCClient.mesa (except for the name)
zSunRPCClientStub.mesa -- copied from zPxVyClientImpl.mesa then edited as described below
zSunRPCServerStub.mesa -- copied from zPxVyServerImpl.mesa then edited as described below
zTozSunRPC.mesa -- imports zSunRPC and exports z (translates calls on one interface into the other & converts between data types in the two interfaces)
zSunRPCToz.mesa -- imports z and exports zSunRPC (translates calls on one interface into the other & converts between data types in the two interfaces)
Issues:
1. multiple instances of clients (esp smarts) wish to register under the same interface name.
1b. explicit reference to PupRPC interfaceRecords. Add extra parameters?
2. some implementations may use the conversation or SHHH parameter to construct /pull out user credentials, names, etc. Either want to add additional parameters for a few procedures or find credentials from other Thrush-internal mechanisms instead.
SunAuthUnix/SunAuthUnixDoc constructs Unix-flavor SunRPC credentials for Cedar clients (need same GV & Sun names!!)
VoiceRopeServerImpl.mesa
Record (credentials) create new, need creator
Play (credentials) authentication of access list
Retain (none) want requestor
Cat (none) create new
Substr (none) create new
Replace (none) create new
SetPermissions (none) authentication of owner
3. some machine-dependent records eg keys. assume byte-order fixed, will revisit if this assumption ever changes
4. want to be able to encrypt keys for possible shipment to workstations (for local manipulation of voice)
5. atoms shipped as strings, return as atoms
Transcription to foo.cr
Rope.ROPE => CedarRope CedarRope: TYPE = STRING
ATOM => CedarAtom CedarAtom: TYPE = STRING
LIST => SEQUENCE len OF Type
INT => LONG INTEGER
PROC => PROCEDURE
NAT => CARDINAL
BOOL => BOOLEAN
CARD32 => LONG CARDINAL
CARD16 => CARDINAL
REF => define the record itself
no .. (no subrange types, no declared array bounds)
no embedded type definitions in records. make new level-one type.
NOTE 1: If you eradicate 16-bit quantities here, then you won't need to remove SunRPC.GetCard16/PutCard16 later (these are intended to be private to SunRPC).
NOTE 2: Note that SunRPC cannot handle NIL refs. It will always pass a full record. If a NIL value is possible/meaningful, then you must encode that in some way within the record, either by adding another boolean field reallyNIL, or by making a special value of some pre-existing field that otherwise could not occur.
Changes to mumblePxVy
cr => Delete Break (Do Operations)
tab => Delete Nest (Do Operations)
Ctrl-M Mesa looks
set format = code
Changes to mumblePxVyfooImpl => mumbleSunRPCfooStub
Add SunRPC, SunRPCAuth to DIRECTORY and IMPORTS
CrRPC => SunRPC
SunRPC.Handle => Handle (add def of Handle)
Handle: TYPE ~ SunRPC.Handle;
SunRPC.PutBool => SunRPCPutBool
SunRPC.GetBool => SunRPCGetBool
SunRPCGetBool:
PROC [h: Handle]
RETURNS [
BOOL] ~
INLINE {
RETURN [SunRPC.GetCard32[h] # 0] };
SunRPCPutBool:
PROC [h: Handle, bool:
BOOL] ~
INLINE {
SunRPC.PutCard32[h, IF bool THEN 1 ELSE 0] };
, s: SunRPC.STREAM => null
[h, s] => [h]
[h, s, => [h,
[s] => [h]
[s, => [h,
s -- search as word and destroy as needed
NOTE: SunRPC.GetCard16/PutCard16 ARE NOT USER PROCEDURES -- they do not maintain word alignment. Change ALL occurrences to GetCard32/PutCard32 and let the compiler widen and narrow as needed. Need also to change VAL[card32] to VAL[CARDINAL[card32]] for unmarshalling enumerated types.
Changes to mumblePxVyClientImpl => mumbleSunRPCClientStub
SunRPC.Call => SunRPCCall
SunRPC.GetErrorProc => SunRPCGetErrorProc
SunRPC.GetResultsProc => SunRPCGetResultsProc
SunRPC.PutArgsProc => SunRPCPutArgsProc
Add placing calls section -- should define in one place and use
Changes to mumblePxVyServerImpl => mumbleSunRPCServerStub
SunRPC.BeginReturnProc => SunRPCBeginReturnProc
add decl before Server proc
SunRPCBeginReturnProc: TYPE ~ PROC [h: Handle];
Change Server proc
(SunRPC.ServerProc has diff type than CrRPC equivalent)
Handle error marshalling if needed.
Define beginReturn proc
beginReturn[h] => SunRPC.StartReply[h]
Add Initialize server section
SunRPC.RegisterServerProc => SunRPC.CreateServer
Add call to SunPMapLocal.SetLocal to register the service with the local port mapper (with correct pgm number)
Data conversion modules
If a NIL value is possible/meaningful, you must check for NIL refs and create appropriate dummy records going in to SunRPC, and turn them back into NIL on the other side. (See note 2 under Transcription to foo.cr.)
As a special case of this, note that ROPEs always emerge from a SunRPC connection as "" rather than as NIL, so either server and client code must be aware of this, or conversion code must handle it.
FinchSmartsImpl.InitFinchSmarts
ThSmartsRpcControl.UnexportInterface
ThSmartsRpcControl.ExportInterface [InterVoice.df]
exports an instance of ThSmarts.Lark (FinchSmarts)
NamesRPC.StartConversation
starts an RPC conversation w/ caller ThSmarts callee Thrush
FinchSmarts.FinchRegister (in ThPartyClientImpl)
imports an instance of ThParty.Lark from specified server
real Register done in ThPartyClientImpl.PostError
FinchSmarts.pd records Finch info incl
RPC.InterfaceName
also requests: MBQueue to serialize all reports
FinchSmartsImpl.info [FinchSmarts.FinchInfo]
records exported interface name, Thrush instance, RPC.Conversation w/server
390908 Thrush 22 TYPE = 4 RECORD, 0 LIST, 6 ATOM, 1 enum, 8 external; 0 PROC
390909 ThParty 19 TYPE = 4 RECORD, 3 LIST, 4 ATOM, 1 enum, 2 addl external; 30 PROC
390910 ThSmarts 0 TYPE, 0 external; 4 PROC
***** Synthesizer 4 TYPE = 1 RECORD, 1 LIST, 0 ATOM, 0 enum, 0 addl external; 1 PROC
390911 SynthesizerServer 0 TYPE, 0 addl external; 3 PROC
390912 VoiceRopeServer 12 TYPE = 4 RECORD, 2 LIST, 0 ATOM, 0 enum, 0 addl external; 18 PROC
390913 LarkTTY 0 TYPE, 0 addl external; 1 PROC
390914 LarkFeep 0 TYPE, 0 addl external; 2 PROC
May 8, 1990 12:34:12 pm PDT
DONE: 41
TYPE = 8
RECORD, 3
LIST, 10
ATOM, 2 enum, 10 external; 30
PROC
need 10 add'l conversions (have 28)
TO DO: 16 TYPE = 5 RECORD, 3 LIST, 0 ATOM, 0 enum, 0 addl external; 29 PROC
VoiceUtils.df??
calling Atom.GetPName with NIL doesn't work
ThParty
GetConversationInfo
GetParty
GetPartyFromNumber
Architecture of voice system SunRPC,
as of September 15, 1990 12:09:29 pm PDT:
This discussion works from the bottom up. The SunRPC system now has three layers, not counting the application layers. See /Finch/PortNotes.tioga for discussions of one such application layer.
SRPCCalls layer.
The ThrushSunRPCCalls interface was renamed, for two reasons: first, to remove the implication that it is specific to Thrush; second, to shorten it.
SRPCCalls defines some new data types:
SHandle, which contains all information needed to establish or reestablish a connection: server name, program and version numbers, timeouts, etc., and some connection flags. SHandles are associated one for one with the RPC.Conversation parameters supplied by clients, and with the SunRPC.Handle values used by SunRPC. Each separate client of an interface must make a separate handle for it. SHandles are monitored records, which guarantee that RPC calls referring to them are serialized. There's a place in an SHandle for a clientData REF.
SHandle.enabled should be set (TRUE) if communication failures should result in automatic attempts to reconnect, cleared (FALSE) otherwise. Clients can set and clear this bit directly. SHandle.connected should not be manipulated by clients.
ReportProc, which permits errors that are not propagated or reported in return values to be reported to clients. A ReportProc may be registered when an SHandle is created.
SRPCCalls.Error has the same parameters as SunRPC.Error. It is the Error used throughout the system for dealing with RPC problems.
Old procedures:
SunRPCGetBool, SunRPCPutBool: generic utilities for use by stubs.
SunRPCProgramCall: the client-side dispatcher for Sun RPC calls. A SunRPC.Handle identifies the client, for compatibility with the past. An SHandle would make more sense; for now, a map is maintained and the SHandle retrieved on every call.
Both the needed SunRPC program/version values (now supplied in the SHandle) and the obsolete Courier values were deleted from the parameter list and the corresponding stubs adjusted.
SunRPCProgramCall reports timeout and other potentially-recoverable errors via SHandle.reportProc, if supplied. It also raises SRPCCalls.Error if a single attempt to reconnect fails, or if the error is not thought to be recoverable. The reconnect will not be attempted if SHandle.enabled is FALSE. The idea is that every time the user tries to do something, or every time the keep-alive process in the client, if any, checks in, new calls will be attempted, and new attempts to reconnect will be made. This client-clocked approach limits connection reatttempts to a frequency compatible with the urgency of the application.
New procedures:
NewRPCConversation: creates an SHandle, an RPC.Conversation (SHHH) value, and a dummy SunRPC.Handle value, associating them all such that each can be obtained from the other. Stores all the client-provided information. serverName must either be a host name or a rope representation of an IP port, of the form "sun#[1.2.3.4]#5 (see interface definitions for more details). The timeoutEnable parameter is not yet used. No attempt is made to connect. The SHHH is returned. The server connection will be made during the first actual call on the interface, usually an interface-level connection call. Successful new connections result in a change to the SHandle.handle, so clients must be sure never to refer to cached values of this handle.
ReleaseConversation: Terminates any server connection, and Sun RPC handle caches. Breaks any Clears the maps relating the three handle-like values, and breaks two-way links. Clears all state variables to avoid confusing clients that continue to refer to the SHandle.
GetSHandle: fetches the SHandle corresponding to an RPC.Conversation (SHHH). There's also a private procedure in the implementation that fetches the SHandle from a SunRPC.Handle. This can be exported if anyone ever finds it useful. Once the SHandle is in hand, the SunRPC.Handle is available as one of its fields.
Stub layer
<I>SunRPCClient interface needs no changes at all. Example: ThPartySunRPCClient.
<I>SunRPCClientStub is only changed in systematic ways. In particular,
ThrushSunRPCCalls => SRPCCalls,
and the redundant program/version parameters are removed from all calls.
As far as I know, no changes will be required on the Server side at all, for any of these systems.
Stuboid layer
This is the additional layer introduced originally to provide type conversion services between Cedar types and those that can be directly encoded in SunRPC packets. Also, this layer included basic interface import services. It has been extended in three ways: extensive error and communication failure recovery; better error and state reporting (in both directions); inclusion of Thrush-level connection management as well as SunRPC level management.
<I>SunImport interface is renamed
<I>SunRPControl. Example:
ThPartySunRPControl. The remainder of the changes are interface-specific. Here is what I did for ThParty:
ThPartySunRPControl.ImportInterface => ThrushConnect. All the information needed both to import the RPC Interface and register with Thrush were combined in this interface. Included are two procedures, one to report Errors and other notable conditions to application-level clients (recall that the so-called Stuboid layer, the other to report specific state information. These are the kind of functions that are provided to FinchSmarts clients by the FinchSmarts level, but one level down.
ThrushDisconnect is added. It will disconnect at the thrush level, but not at the RPC level (not really necessary). An optional parameter permits the SHandle.enabled bit to be cleared, suppressing attempts at all levels (including the Stuboid level) to reconnect automatically when problems arise.
ThrushReportState is added, to permit Thrush-level connection and enable information to be forwarded from ThSmarts.Checkin state reports. ReportState can only be used to clear these indications, not set them. enabled is cleared when the server reports that it is out of service indefinitely.
ReleaseConversation breaks connections at all levels and releases any stub-level data structures. Its use is optional, since dangling connections don't cost much.
The ReportState procedure that the client can register with the ThParty client stuboid reports thrush-level connection, rpc-level connection, and enabled bits, as well as the current values to be supplied for PartyID and SmartsID in one's own credentials during calls on the ThParty interface. Reason: the correct values to use will change if for any reason the automatic error recovery code in the Stuboid ever reregisters with Thrush.
<I>To<I>SunRPC (in this case, ThPartyToThPartySunRPC) has been extensively revised, to implement the new multi-level registration code, to adjust to changes in the underlying layers, and to implement all the new error management and state reporting code. The SHandle clientData field for this interface is called a PHandle; it contains whatever is necessary to maintain the state model and automatically reconnect.
This module locks the GetInfo and the ReregisterOnError private routines, in a feeble attempt to prevent these critical functions from producing nonsense when concurrent calls on the same handle occur (shouldn't happen anyway). Since calls are passing through the stuboid in both directions, any locking at all is dangerous here, and quite likely not necessary. In fact, the only reason that locking is needed at the SRPCCalls level is that some ThParty calls do not supply a SHHH handle, and have to have one invented for them. This can result in concurrent call attempts on the same handles.
ThPartyToThPartySunRPC can be used as a model for other implementations.
Application layer
See /Finch/PortNotes for a description of changes to one client, in response to the modifications described here.
Things to check up on:
Importing: UDP thingie for named services is more complicated and involves contacting the remote service. That's good; apparently no such contact is needed when importing by number; that's bad. Check with PTZ.
Export of interfaces that are bound to by explicit address: should they update the port mapper? I don't think anyone uses it. Should the exportInterface code be generic? Except for sunPgm and sunPgmVersion, there's nothing specific to any given interface in there. True of a number of routines in the Import side, too, for simple services. Check whole thing with PTZ.
VoiceRopeServer, LarkFeep, SynthesizerServer (following the lead of VRS) Export code does not remember old port numbers and resupply when re-exporting. Maybe it doesn't matter, but it's unclean. Discuss.