RFC 722

Thoughts on Interactions in Distributed Services

πŸ“… published September 1976, from ietf

Okay bestie, let's start with the title block πŸŽ€ It's from the Network Working Group, and it's Request for Comments: 722 πŸ¦‹ Written by Jack Haverty (MIT), dated Sept 1976, with NIC #36806 on it too. Heads up: this block doesn't list a category, and it doesn't say what it obsoletes or updates πŸ’…

I. ABSTRACT ✨

So this paper is about designing distributed services 🌸 specifically how programs talk to each other across different network sites to run some service. The ideas mostly come from hands-on experience with various service protocols on the ARPANET [Reference 1] πŸ’œ

The paper builds a model of how programs interact. It calls out the key features that make reliable, responsive services easier to build πŸ‘‘ Those features come from problems seen with various ARPANET protocols, and from designing and maintaining programs that use those protocols to run a service. Lowkey the real pain points 😭

Using that model as a template, the paper lays out the general architecture of one possible interaction protocol 🧚 It's a foundation that specific protocols can be built on, which makes services easier to implement and maintain, and makes them feel reliable and responsive to the customer πŸ’– This is meant as an intro to one specific instance of that kind of protocol, called the RRP, which is defined in one of the references ✨

II. OVERVIEW AND TERMINOLOGY πŸ¦‹

This paper looks at the interaction of two programs that support some network service. It builds a model of how a class of these apps interact, and shares some thoughts on goals and what good implementations look like 🌈 The model is derived from a proposal [Reference 2] for mail-handling systems. Terminology gets highlighted by capitalization, so keep an eye out πŸ‘€

Lots of network stuff involves programs talking directly, with no human involved or watching πŸ€– Examples include an advanced mail-handling system, or any kind of multi-site data base manager.

These programs are called SERVERs. They're the users of some mechanism that provides the communication and synchronization they need. The particular facility the servers implement is called a SERVICE. Servers for any given service can be written in several languages and run in different system environments on different kinds of computers πŸ“ The entity that uses the service is the CUSTOMER.

Servers interact during ENCOUNTERs, which are the periods when two servers are in communication 🫢 An encounter begins when one server establishes a CHANNEL, a bidirectional communication link with another server. The interaction happens through exchanging information over that channel. The conventions for that exchange are defined by the PROTOCOLs for the interaction.

The big theme here is a model for a particular class of process interactions πŸ’… It can be the basis for lots of services where the interactions are fairly simple. Services that fit this category interact in a way that can be modeled by a REQUEST-REPLY DISCIPLINE, which gets defined in this paper.

There's a set of guidelines and goals here too, covering ease of implementation and reliability of server operation 🌸 These guidelines can help people formulate protocols for specific services.

They can also be a basis for a general process interaction protocol, by pulling out the primitives and operational concepts that would be common to a protocol for pretty much any such service 🧚

So from these ideas, you can build a foundation protocol, then extend it for particular services by adding primitives specific to each one ✨ The RRP [Reference 4] is one such possible protocol. It gives you basic primitives to control the interaction between servers, plus a mechanism for extending those primitives to include service-specific operations πŸ’–

The discussion is mainly here to explain the basis for the design of the RRP, and to bring up some general design issues for services πŸŽ€

III. THE REQUEST-REPLY DISCIPLINE πŸŽ€

The class of services relevant to this discussion is the set whose interactions can be performed in the following way πŸ‘‘

Two servers have established a channel by some external means. A single interaction between servers starts with one server, called the REQUESTER, issuing a request. The server receiving that request, the RESPONDER, issues a REPLY. The requester reads the reply sequence to figure out whether the request was successful, failed, or partially failed, and then takes appropriate action. That whole sequence of events is called an EXCHANGE. It's basically a subroutine call in a simple single-processor operating system πŸ¦‹

This model is called the REQUEST-REPLY DISCIPLINE of program interaction. Important note: it's only a model of program behavior πŸ™ˆ It doesn't necessarily rule out services that need some pipelining of requests for efficiency in long-delay situations. Honestly, most network services would need those measures, but their interactions can still be reduced to the request-reply model πŸ’€

At any time, one of the partners is in control of the interaction, and that partner is the MASTER of the interaction. The other partner is the SLAVE 🫢 In the simplest cases the requester is always the master, though that isn't always true in particular implementations, such as the RRP [Reference 4].

IV. CHARACTERISTICS OF AN INTERACTION MECHANISM 🌈

These desirable characteristics of an interaction mechanism come from experience with program communication across a bunch of ARPANET applications: message services, file transfer, Datacomputer, and remote job entry apps 🧚

While building those systems, several qualities kept coming up as things the substructure underneath them should have πŸ’œ These characteristics make it easier to write and debug servers, keep reliability up, and provide services that respond to customer needs, all while avoiding disruptions of service 😭

The qualities are presented along with a discussion of the effects they're meant to produce in the related services. It has to be emphasized that this discussion is about a class of simple services, and might not be a great fit for more complex applications ⭐

  1. Servers must be able to transfer data precisely, keeping its structure and semantic meaning, even though the computer systems they run on are super different from each other πŸ“
  2. Synchronization and timing problems caused by the characteristics of the communications link must be isolated and handled separately from any that might be characteristic of the service itself πŸ”₯
  3. Since services may want to provide expanded facilities as they're used and developed, a mechanism must be included to let the service protocol evolve 🌱
  4. Since various programs that act as servers may be under simultaneous development, care must be taken to make sure servers with different capabilities interact reliably, keeping at least the same level of service as before πŸ‘‘
  5. The mechanisms for extending the facilities must avoid requiring servers to be modified when new capabilities get introduced, but they shouldn't impede progress by maintainers who are anxious to ship a new or experimental service πŸ¦‹

These qualities fall into three categories: data precision (1), process synchronization (2), and service enhancement (3, 4, 5) πŸŽ€ Each one gets its own discussion in the sections that follow, including what it means and how it affects the service, with some references to related problems in current and past services ✨

Since these considerations are common to a lot of possible services, it makes sense for the interaction protocol to include them in its machinery as much as possible πŸ’… That way, services that are carefully designed can inherit these properties from the interaction substrate πŸ’–


V. PRECISE DATA TRANSFER πŸ’œ

Precision in data transfer lets the semantic and structural information in the sender's instance of a datum get reproduced in the receiver's image of that datum, even when the systems involved represent it in totally different ways 🌸

For programs to provide powerful, reliable capabilities, they have to interact using data that's meaningful to the particular service involved πŸ‘‘ The interaction mechanism needs to let services define their own relevant data types, and transfer those items efficiently and precisely. This gives you a 'standard' for data, so the service's designers can focus on the higher-level issues they actually care about 🧚

Data of a given type should be recognizable as that type without needing any context πŸ” The mechanism should also let new data types get handled by older servers without error, even though those servers can't interpret the semantics of the new data 🫢

This characteristic lets services get designed around the abstract data they need to function, without constantly worrying about the particular formats it's represented in on various machines πŸ¦‹

For example, servers may need to transfer a datum identifying a particular date, and that date may be represented inside systems in different forms πŸ“… The data transfer mechanism should be able to transfer it as a date per se, rather than as a strict pattern of bits or characters πŸ’€

Here's another one: in current FTP-based mail systems, messages often contain info with significant semantic meaning, and that meaning gets lost or obscured when it's transferred between sites 😭 Take a file specification. It effectively loses all of its identity as one once it's translated into a simple character stream. People can usually recognize those streams as file names, but building a program to do that reliably is often extremely difficult, time-consuming, and inefficient πŸ™ˆ So services that should be easy to provide to the customer, like automatic retrieval of relevant files, end up being difficult and unreliable πŸ’”

Some success has been had with certain data, like dates and times, by defining a particular character pattern that, if seen in a particular context, can be recognized as a date or time 🌈 Each of these cases got handled individually, by defining a format for that one piece of data. The format depends to some extent on the datum showing up in a particular context, so it isn't unique enough to be identifiable outside that context πŸ“

A particular service can achieve data precision through meticulous specification of the protocols that transfer the data πŸ’… That need is widespread enough, though, that it makes sense to consider putting a facility for data precision inside the interaction mechanism itself πŸ‘‘

The major effect of this would be to make reliable, responsive services easier to design, by relieving the service's designers from having to worry about the very low-level

details of data representation, which are usually the least interesting but highly critical parts of the design 🧠✨ By isolating the data transfer mechanism, this architecture also promotes modularity of implementations, which can reduce the cost and time needed to implement or modify services. πŸ’…

VI. Process Synchronization πŸ”„

A major source of problems in many services involves synchronization of servers interacting over a relatively low-bandwidth, high-delay communications link. πŸ₯Ί

Interactions in most services involve issuing a command and waiting for a response. The number of responses which can be elicited by a given command often varies, and there is usually no way to determine if all replies have arrived. Programs can easily issue a request before the responses to a previous request have completed, and get out of synchronization if a response is incorrectly matched to a request. 😭 Each server program must be meticulously designed to be capable of recovering if an unexpected reply arrives after a subsequent command is issued. 🫠

Note that, for reliable operation, it is always necessary that each response cause a reply to occur, at least in the sense that the request is confirmed at some point. πŸ’– No service should perform a critical operation, such as deleting a file, which depends on the success of a previous request unless it has been confirmed. Requests in current protocols which do not appear to cause a reply may be viewed as confirmed later, when a subsequent request is acknowledged. While such protocols work, they are more opaque than desirable, and consequently more difficult to implement. πŸ™ˆ

Deleting a file based on a request nobody confirmed is a vibe-killer. Confirm first, then do the scary stuff. πŸ’€

These characteristics of protocols have often resulted in the implementation of ad hoc methods for interaction, such as timeouts or waits of sufficient length to assure correctness in an acceptably high percentage of situations. πŸ•°οΈ Often this has required careful tuning of programs, as experience in using a protocol shows which commands are most likely to cause problems. Such methods generally result in a service which is less responsive, powerful, or efficient than desirable, and expensive to build and maintain. πŸ’Έ

Additionally, protocol specifications for services have often been incomplete, in that an enumeration of the responses which may occur for a given command is inaccurate or non-existent. πŸ“œ This greatly complicates the task of the programmer trying to construct an intelligent server. In most cases, servers are slowly improved over time as experience shows which responses are common in each instance. 🐒

The synchronization problems mentioned above are in addition to those which naturally occur as part of the service operation. Thus, problems of synchronization may be split into two classes: those inherent in the service, and those associated with the interaction mechanism itself. 🧩

Construction of reliable, responsive servers can be assisted by careful design of the interaction mechanism and protocols. ✨ An unambiguous, completely specified mapping between commands and responses is desirable. Synchronization considerations of the two types can be attacked separately. An interaction mechanism which handles its own synchronization can be provided as a base for service designers to use, relieving them of considerations of the low-level, protocol-derived problems, by providing primitives which encourage the design of reliable services. πŸ‘‘

To achieve a reasonable effective bandwidth, it is usually desirable to permit interacting programs to operate in a full-duplex fashion. Significant amounts of data are often in transit at any time. πŸš€ This magnifies the problems associated with interaction by introducing parallelism. The interaction mechanism can also be structured to provide ways of handling these problems, and to provide a basis on which servers which exploit parallelism can be constructed. πŸ¦‹


Many of these problems are too complex to warrant consideration in any but the most active services. As a result, services are often constructed which avoid problems by accepting inefficiencies in their operation, as mentioned above. πŸ™ƒ Provision of an interaction mechanism and primitives for use by such services would promote efficient interaction even by simple services which do not have the resources to consider all the problems in detail. 🧚

VII. Service Enhancement πŸŽ€

When particular programs implementing a service are undergoing development simultaneously by several organizations, or are maintained at many distributed sites, many problems can develop concerning the compatibility of dissimilar servers. πŸ˜΅β€πŸ’«

This situation occurs in the initial phase of implementing a service, as well as whenever the protocols are modified to fix problems or expand the service. Virtually every interaction protocol is modified from time to time to add new capabilities. Two particular examples are the TELNET protocol and mail header formats. πŸ“¬

In most cases, the basic protocol had no facility for implementing changes in an invisible fashion. This has had several consequences. 🫣

First, it is very difficult to change a protocol unless the majority of concerned maintainers are interested in the changes and therefore willing to exert effort to change the programs involved. This situation has occurred in previous cases because any change necessarily impacts all servers. The services involved therefore often stagnate, and it becomes inappropriately difficult to provide a customer with a seemingly simple enhancement. πŸ₯€

Second, when protocols change by will of the majority, existing servers often stop working or behave erratically when they suddenly find their partner speaking a new language. πŸ€– This is equally disconcerting to the service customer, as well as annoying to the maintainers of the servers at the various sites affected. 😀

These problems can be easily avoided, or at least significantly reduced, by careful design of the interaction protocols. In particular, the interaction mechanism itself can be structured to avoid the problem entirely, leaving only those problems associated with the particular service operations themselves. 🌸

The interaction machinery should be structured so that the mechanisms of the interaction substrate itself may be improved or expanded in a fashion which is absolutely invisible to current servers. 🫧

  1. No server should be required to implement a change which is unimportant to its customers.
  2. No server should be prevented from utilizing a new facility when interacting with a willing partner.
  3. Service should not be degraded in any way when a new protocol facility is made available.

In cases where a single service is provided by different server programs at many sites, it is desirable for the various sites to be able to participate at a level appropriate to them. 🌈 A new server program should be able to participate quickly, using only simple mechanisms of the protocol, and evolve into more advanced, powerful, or efficient interaction as desired. Sites wishing to utilize advanced or experimental features must be allowed to do so without imposing implementation of such features on others. Conversely, sites wishing to participate in a minimal fashion must not prevent others from using advanced features. In all cases, the various servers must be capable of continued interaction at the highest level supported by both. 🀝

The goal is an evolving system which maintains reliability as well as both upward and downward compatibility. πŸ¦„ The protocol itself should have these characteristics, and it should provide the mechanisms for service interaction protocols to be defined which inherit these qualities. πŸ’œ

VIII. Structuring an Interaction Mechanism 🧱

The qualities presented previously should provide at least a starting point for implementation of services which avoid the problems mentioned. The rest of this paper addresses issues of a particular possible architecture of an interaction mechanism. πŸ—οΈ

The design architecture splits the service-specific conventions from those of the interaction per se. An interaction protocol is provided which implements the machinery of the request-reply model, and includes handling of the problems of data precision, synchronization, and enhancement. This protocol is not specific to any service, but rather provides primitives, in the form of service-designed requests and replies, on which a particular service protocol is built. 🍰

An actual implementation for a particular service could merge the code of the interaction protocol with the service itself, or the interaction protocol could be provided as a 'service' whose customer is the service being implemented. πŸͺ„

The goals of this design architecture follow.

  1. Provision of a general interaction mechanism to be used by services which follow a request-reply discipline. Services would design their protocols using the primitives of the mechanism as a foundation. πŸ›οΈ
  2. INTERACTION MECHANISM EXTENSIBILITY. The interaction mechanism may be expanded as desired without impacting existing servers unless they wish to use the new features. 🌱
  3. SERVER EXTENSIBILITY. Servers can be implemented using the most basic primitives. Implementations may later be extended to utilize additional capabilities to negate some of the inefficiency inherent in a strict request-reply structure. πŸ›Ή
  4. SERVICE EXTENSIBILITY. The primitives permit a service to be expanded as desired without impacting existing servers in any way unless they wish to use the new features. 🎈
  5. SERVER COMPATIBILITY. Within the set of servers of a given application, it is possible to have different servers operating at different levels of sophistication, and still maintain the ability for any pair of servers to interact successfully. πŸ’ž

These goals involve two basic areas of design. First, the interaction mechanism itself is designed to meet the goals. Secondly, guidelines for the structure of the particular service's protocols are necessary, in order for it to inherit the qualities needed to meet the goals. πŸ”§

IX. Partitioning the Problem 🧩

In defining the interaction mechanism itself, the problem may be simplified by considering two areas of concern separately. πŸͺž

  1. The characteristics and format of the data conveyed by the channel may be defined.
  2. The conventions used to define the interaction may be defined, in terms of the available data supported by the channel.

For purposes of this paper, the data repertoire and characteristics of the channel are assumed to be as described in [Reference 3] and summarized in an appendix. Discussions of the interaction between servers will use only the abstract concepts of primitive and semantic data items, to isolate the issues of interaction from those of data formats and communication details, and therefore simplify the problem. 🫧

Additionally, actual implementation of a mechanism following the ideas presented here can be accomplished in a modular fashion, isolating code which is concerned with the channel itself from code concerned with the interaction behavior. πŸ“

The interaction mechanism provides primitives to the service designer which are likewise defined in terms of the data items available. Service designers are encouraged, but not required, to define interactions in terms of these data only. πŸ’…

X. The Primitives ✨

The interaction mechanism assumes the existence of a channel [Reference 3] between two servers. Two new semantic data types are defined to implement the

These are, unsurprisingly, called CONTROL REQUESTs and CONTROL REPLYs. Each of these data items contains at least two elements. πŸ’–

  1. The TYPE element identifies a particular type of request or reply. πŸŽ€
  2. The SEQUENCE element is used to match replies to their corresponding request. 🧚

Other elements may appear. Their interpretation depends on the particular type of request or reply in which they appear. ✨

The interaction protocol itself is defined in terms of control requests and control replies. A very small number of request and reply types is defined as the minimal implementation level. Additional request and reply types are also defined, for use by more advanced servers, to provide additional capabilities to the service, or simply to increase efficiency of operation. 🌸

Two additional data items are defined, called USER REQUESTs and USER REPLYs. These are structured like requests and replies, but the various types are defined by the service itself, to implement the primitives needed in its operation. πŸ’…

Control and user requests and replies are generically referenced as simply REQUESTs and REPLYs. πŸ¦‹

The protocol of the interaction has several characteristics which form the basis of the request-reply model, and attempt to meet the goals mentioned previously. It's giving architecture, honestly. πŸ‘‘

  1. Every request elicits a reply. πŸ’œ
  2. Every reply is associated unambiguously with a previous request. 🫢
  3. Each server always knows the state of the interaction, such as whether or not more data is expected from its partner. πŸ”₯
  4. The protocol definition includes enumeration of the possible responses for each request. Service protocols are encouraged to do likewise for user requests and user replies. πŸ“
  5. Servers who receive requests of unknown type issue a response which effectively refuses the request. Servers attempting to use advanced features of a protocol 'rephrase' their requests in simpler terms where possible to maintain the previous level of service. πŸ™ˆ

The minimal implementation will support interaction almost exactly along the lines of the request-reply discipline. Simple, clean, iconic. ✨

Extensions to the minimal configuration are defined for two reasons. First, the strict request-reply discipline model is inefficient for use in high-volume situations because of the delays involved. Several extensions are defined to cope with this problem. Thus, although the interaction is based on such a discipline, it does not necessarily implement the interaction in that fashion. Second, additional primitives are defined which provide some standard process synchronization operations, for use by the services. 🌈

The protocol architecture presented here is defined in detail in an associated document. [Reference 4] πŸ“–


Appendix I -- The Channel πŸ¦‹

The following discussion is a summary of the ideas presented in [Reference 3], which should be consulted for further detail. 🫢

The communication link between two servers is termed a CHANNEL. Channels provide bidirectional communications capabilities, and will usually be full-duplex. The programs involved establish the channel as their individual applications require, using some form of initial connection protocol. πŸ’–

The channel acts as an interface between servers. It conveys abstract data items whose semantics are understood by the programmers involved, such as INTEGERs, STRINGs, FILE PATH NAMEs, and so on. Because the users of the channel may operate in dissimilar computer environments, their communication is defined only in terms of such abstract data items, which are the atomic units of information carried on the channel. The program implementing the channel at each site converts the data between an encoded transmission format appropriate to the particular communication link involved, and whatever internal representational form is appropriate in the computer itself. 🧚

The channel protocol provides a mechanism for definition of various types of data items of semantic value for the particular service concerned, for example, possibly, user-name, set, syllable, sentence, and other data items of interest to the particular service. The channel provides a mechanism for transportation of such user-defined data from host to host. 🌸

The channel may actually be implemented by one or more separate encoding mechanisms which would be used in different conditions, initially, the channel machinery would provide a rudimentary facility based on a single mechanism such as the MSDTP [Reference 3]. πŸ“

The mechanism is not dependent on the existence of actual line-style network connections but will operate in other environments, such as a message-oriented (as opposed to connection-oriented) communications architecture, and in fact is more naturally structured for such an environment. Honestly the message-oriented bit is so underrated. πŸ’…


XI. References πŸ“š

[1] Network Information Center, ARPANET Protocol Handbook, April, 1976.

[2] Broos, Haverty, Vezza, Message Services Protocol proposal, December, 1975.

[3] Haverty, Jack, Message Services Data Transfer Protocol, NWG RFC 713, NIC 34729, April, 1976.

[4] Haverty, Jack, RRP, A Process Communication Protocol for Request-reply Disciplines, NWG RFC 723, NIC 36807, (to be issued) πŸŽ€

πŸ“¦ where this page comes from