RFC 684
Commentary on procedure calling as a network protocol
RFC 684: A Commentary on Procedure Calling as a Network Protocol π
Network Working Group πΈ RFC #684 β¨ NIC #32252 April 15,1975 π¦
Author: Richard Schantz, BBN-TENEX π
Okay bestie, the title block doesn't list a category or an "obsoletes" or "updates" line, so I'm not making any up. π
Preface π
Okay so this RFC is the first step in a plan to get people talking about how to design a distributed computing system π£οΈβ¨ It's looking at the approach in RFC #674, which everyone calls the "Procedure Call Protocol" (PCP) π The main goal here is to point out what we think are the shortcomings of that design approach.
Not the first time we've critiqued PCP, btw π During the early PCP design stages we met the PCP designers for a short while and suggested a bunch of changes, and a lot of them ended up in PCP Version 2 π But the vibe of those suggestions was totally different from this note. The original ones, and some later ones, were mostly about implementation details. This note is more about the concepts underneath the PCP design than the PCP implementation π§
We're sharing this because it raises issues that haven't been properly dealt with yet π The PCP designers deserve major props for writing up their ideas in detail, which gives everyone a natural starting point for talking about distributed system design concepts π The whole point is to get people interacting who are into distributed computing, so that maybe we end up with systems whose designs don't block them from being used in projects other than the one they were originally made for π
Huge thanks to Bob Thomas of BBN-TENEX, who has had tons of discussions with us about this and shares the same point of view π«Ά
Introduction π¦
Okay, so, the Procedure Call Protocol (PCP) and how it's used inside the National Software Works (NSW) project actually tackle a lot of the problems you run into when you try to get independent computing systems to work together on one distributed computation π₯ BUT we think its design has flaws that should stop it from being used everywhere, and those flaws limit how useful it is overall π
We're not objecting to PCP, as it's currently defined, being used as the base-level implementation for the NSW project π ββοΈ It's already too late for that kind of objection anyway π PCP might honestly work really well for NSW, since both projects were moving forward at the same time and have probably influenced each other π§ What we're actually objecting to is the "PCP philosophy" π We really don't want this type of protocol to become the de facto network standard for distributed computation, and we want to influence where this effort and similar ones go next π―
Some of the things we don't like about PCP might just be differences in personal taste, and philosophers have long said you can't argue about taste π We've tried to avoid that kind of argument in this document. Instead, we look at PCP through what we've actually learned from building distributed systems π οΈ Looked at that way, we think PCP and its underlying philosophy have flaws that make it a bad fit as a general purpose protocol and virtual programming system for building distributed software π
Here's our take: PCP is probably complete, meaning you can probably do anything you need with its primitives β¨ So the key question isn't whether this function or that function can be supported π The question that matters to us is how easy it is to do the things that experience has shown are important in distributed computing π On top of that, a programming discipline built for network applications should pay special attention to steering its users away from things that systems programming in general, and network programming in particular, have shown are pitfalls in system implementation β οΈ
A Point of View π
Let's be clear, we're fully behind the parts of the PCP design effort that systematize how distributed elements interact and agree with each other to support inter-machine computing π«Ά That includes defining the different types of replies, standardizing the data structure format for exchanges between machines, and the process creation primitives that stretch across machine boundaries π These ideas are basic, and any distributed system definition has to include them π Our main concern is NOT with any of that stuff π
What we DO take issue with is PCP's underlying premise: that the procedure calling discipline is the starting point for building multi-computer systems π ββοΈ That premise gives you a model with a central point controlling the entire algorithm, when a more natural approach for networks is distributed control, where cooperating independent entities interact through shared communication paths π¦ Procedure calls might be a good fit for some applications, sure β¨ But we don't think they can directly or accurately model the interactions and control structures that show up in lots of distributed multi-computer systems π«
Now, PCP supporters might say, "who cares what you call it, it's doing the same thing" π Our response: it really matters to have a clear, concise model of distributed computation π§ The PCP model doesn't force "poor implementation" of distributed systems, but it also doesn't make "good implementation" any easier, and it doesn't stop ill-advised programming practices either π¬ A model that focuses on the dynamic interconnection of somewhat independent computing entities fits better with defensive programming, and we've found defensive programming is fundamental to building usable multi-machine implementations π
The rest of this RFC goes through some of the shortcomings we see in a procedure call protocol π
Limitations of Procedure Calling Across Machines π§
Okay, first and foremost, our argument is that procedure calling should NOT be the basis for multi-machine interactions π ββοΈ We think a request and reply protocol, along with suitably manipulated communication paths between processes, is a model that fits the situation a network puts us in much better πΈ In a network you've got autonomous computing entities that have agreed to cooperate, not a master process forcing a certain body of code to run to get its computing done π So in that setup, it's best to ask a process to do something indirectly (by request) rather than directly (by procedure call), so the integrity of each process stays intact π
Procedure calling is usually a super primitive operation π€ Its implementation often needs only a single machine instruction β‘ And it's generally not part of the operating system's domain π [The Multics intersegment procedure calling mechanism may be an exception to this, until linkage is complete. In the remote PCP case, however, linkage can never be complete in the sense of supporting a fast transfer of control between modules]. Processes and communication paths between processes, on the other hand, are undeniably operating system constructs π₯οΈ In an environment where local procedure calling is "cheap," blurring the line between a local call (cheap in time and effort) and a remote call would be ill-advised π A remote call obviously takes a huge amount of effort from the "PCP system," if not from the PCP user too π We also think blurring the local/remote distinction at the procedure call level will show up as more frequent use of a less efficient local procedure calling mechanism π
Interprocess communication is a different story π¦ At least for stream or message oriented channels (not just interrupt signals), it's generally seen as having a significant cost attached πΈ Sending a message is always an interprocess action, and it always needs system intervention π« The gap between the IPC of local processes and the IPC of remote processes isn't nearly as big as the gap between local and remote procedure calling β¨ PCP kind of suggests a model where processes exist that span machine boundaries to provide inter-machine subroutine calling π€ But the PCP documentation hasn't pushed the idea of a process spanning machine boundaries, and honestly, that's the right call, because creating one would cause endless problems π Since procedure calling is more of an intra-process idea, it makes more sense to take the interprocess communication framework and extend it so it has one uniform interpretation both locally and remotely π instead of stretching the procedure calling model π§ We also believe a model that relies on procedure calling as its basis doesn't account for the special nature of the network environment, and that a message passing model can handle that environment way better π
We also think programming as a whole, even purely local computing, would benefit from paying more attention to reliability and robustness π‘οΈ Those things have come to the forefront because of experience with an often unreliable network and collection of hosts π An IPC model puts the spotlight on the connections between disjoint processes, which reinforces the idea that distributed computing happens by joining separate entities together π«Ά That makes defensive programming and error handling techniques feel totally appropriate π PCP is, we think, aimed at distributed system builders, not end users (for example, an RSEXEC user) π©βπ» So avoiding the network, interconnection issues, and relative costs could backfire if the goal is to build usable network systems π
Along similar lines, the whole idea of inter-machine procedure calling basically extends the address space of a single process π€― In effect, there is a single locus of algorithm control (though maybe not a single locus of execution) π That might work great for a "local" computation where the parts are strongly bound together π But our experience building working distributed systems has shown us the value of a model with multiple loci of control and execution πΈ In that kind of model, a computation gets carried out through agreements on the method and type of information exchange and synchronization, rather than at the direction of one central entity π¦ We think a process with distributed control and execution is in a much better position to naturally cope with the many vagaries that come up in a network environment πͺ
The unmistakable trend in systems programming is toward inviolable (protected) process structures with external synchronization π That's how people cope with complex debugging tasks and with how hard it is to make system changes π οΈ We think that trend is better supported by a message passing model than a procedural
model of computation. Plus, okay, we feel that network programming techniques should be applied to local computation, not the other way around π π
Some Particulars β¨
Okay, so in the list below, we get specific about the situations where we think the PCP concept might be weak as the basis for a network programming system π§ For some of these examples to make sense, you should be pretty familiar with the PCP documents issued as RFC 674 π
- Recovery from component malfunction can be super hard for a process that isn't the central control (aka a process that's getting manipulated by having its procedures executed) π Is network trouble, for example, supposed to be modeled as a forced procedure call to some error recovery routine? Honestly, these are exactly the moments where distributed control is the better model π Think about introducing an inferior to another acquaintance, then handing the new handle over as a parameter to a later procedure call in the inferior. The inferior just blindly uses that parameter to talk to the other process, which shows how the superior is basically in control of everything π The inferior never actually finds out about a new communication path to a new process. The inferior environment (as kept up by the PCP "system") got changed by the superior, with no active notification to the inferior. Weird, right? This makes user coded error recovery kinda awkward, ngl π
- Process manipulation can sometimes break the principles of modular programming π It seems way better to be able to debug the pieces of a computation separately, and then only worry about how they synchronize, so you end up with a totally debugged system β¨ With PCP in its fullest sense, the danger of error propagation seems bigger, because a process has the power to make an arbitrary procedure run and to read and write remote data stores without the remote process actively taking part π¬
- Initialization sequencing is a big question mark π€ Can we assume a proper initialization sequence if our procedures are called remotely? Does every procedure have to contain code that checks whether the call is proper and correctly sequenced? A model where each remote process is an active computing element seems much better at conveniently applying protective standards to the code and data it wraps up π«Ά
- Long term parallel activity isn't modeled very conveniently in PCP π¦ That's a problem, because we need it to handle all sorts of asynchronous producer/consumer process relationships. The synchronization is geared more toward a one-to-one call and return, instead of the asynchronous nature and multiple returns for a single request that you see in lots of network services. On top of that, low priority, preemptable background tasks are hard (impossible?) to model in a procedure call environment π
- Communication paths aren't treated as abstract objects that are independent from the actual entities they connect, so they can't be used in some useful ways (e.g. to carry non PCP messages) π Also, since paths aren't objects, there's no concept of passing a communication path to an inferior (or an acquaintance) without having to create a new "connection" (whether or not that turns out to be a physical channel). Passing paths is often super useful for subcontracting requests to inferior processes. Doing that within PCP requires the calling process to cooperate (i.e. to use the new connection handle), which again seems to violate the concepts of modular programming π ββοΈ The other option in PCP is to have the superior relay the later communications to its created inferior, but the effort involved would probably stop anyone from using this technique for subcontracting π
- Periodic but short interactions (i.e. a few words exchanged) are too much for PCP, which feels way too complicated for this kind of processing π§ An example is the way the TIP uses the TENEX accounting servers (see RFC #672). And honestly, PCP is probably much too complex for implementation on a small host π There also doesn't seem to be a definition of what a minimum implementation for a host/process could look like if it didn't, or couldn't, handle everything that's been developed.
- Persistence and priority servicing get awkward in the PCP model πΈ It may become awkward or resource consuming for a service program to do things like queue operations for execution at a later time (persistence), or at a more opportune time (priority servicing mechanism). Those implementations may need dummy returns and changes to the controlling fork concept, or they may need processing forks kept alive over long periods of inactivity π«
- Splicing a process to a service shouldn't always let that process influence the service process environment in any direct way π¨ How can a service process in PCP stop a malicious user from splicing to it and then introducing it to an arbitrary number of processes, which overflows the table space in that process? All of that could happen without ever executing a single instruction of user written code. This difficulty is a consequence of the PCP notion of having one process manipulate the environment of another without its active participation in those actions. Yikes, bestie π±
- Doesn't it say something that the network PCP process implementation is so much neater than the TENEX PCP process implementation (since TENEX doesn't have a general IPC facility)? π¦ It suggests that message passing and communication facilities supplied by the "system" are a sound basis for multi-process implementations. Maybe such facilities should be primitively available to the distributed system builders who will use PCP π
- There's a question about whether PCP is an implementation virtual machine (language), or an application virtual machine (language) π€¨ In other words, is PCP meant to be used to build systems that manage distributed resources, or is it meant to be an end product that makes network resources easier for the everyday, ordinary programmer to use (e.g. makes the network itself transparent to users)? One gets the feeling the designers had both goals, and neither one is totally satisfied π₯² If we take the former goal, we believe most of the complexities (e.g. network trouble, broken connections, etc.) and possibilities (e.g. redundant implementation, broadcast request, etc.) of network implementations aren't handled adequately. In this view, the NSW framework (Works manager, FE) is the distributed system that uses the PCP implementation language. We don't see how using PCP in this context gives you either an extra-reliable system through component redundancy, or a persistent system that can tolerate temporary malfunctions. If you go with this view, then it doesn't seem right that the objects running under the created system (i.e. the tools that run under the PCP implemented Front End, Works Manager, and TBH monitor) should also be aware of or use PCP. If we consider the latter goal, that PCP implements a virtual machine to be presented to all programmers for making distributed resources easy to use, then it's clear that PCP, with its manifest concern for object location, doesn't provide the desirable properties of network transparency πβ¨
Our conclusion is that procedure calling is not the appropriate basis for distributed multi-computer systems, because it can neither directly nor accurately model the network environment π The PCP virtual programming system may be inadequate for implementing many distributed systems, because the complexities and possibilities unique to the network environment aren't provided for at this basic level ππ
π¦ where this page comes from
- ietf: rfc684 1975-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms