One Size Fits All (by )

However, that's still a rather low-level interface for applications; for a start, the messages are just blocks of binary data, with no standard way of marking successful and unsuccessful responses to requests, no standard way of specifying different types of request that may be made of the same endpoint, and so on.

And as I mentioned above, applications desire a wide array of types of service.

For a start, some like to think in terms of streams of bytes, while others like to think in terms of streams of messages. Most Internet applications use TCP, which is byte oriented, but then they usually have to add their own message framing on top (from using CR+LF to terminate a request to conventions such as balancing parenthesis), which seems unfortunate, since the network itself can benefit from knowing what the application-level message boundaries are (TCP, for example, may queue data in the OS before passing it to the application, in order to deliver the byte stream in order; yet many applications would not mind if incoming requests arrived out of order, as long as the bytes within each request were in order; TCP may have complete requests sitting in the input buffer, kept from the application until all the previous requests are complete and ready to pass in, since it does not know what the request boundaries are). On the other hand, given a message-based protocol, one can easily provide byte-level service (or word-level, for any word size, or record-level) by formatting the messages as an array of one or more bytes, words, or records, depending on how many were submitted at once, with no problems; after all, this is roughly what TCP does when splitting the byte stream into segments for transmission. Therefore, we can safely provide the application with a message-level protocol, and it may trivially use that to convey streams of records if it so wishes; particularly if the protocol is not so simplistic as to handle a large number of very small messages to the same destination as a stream of very small network-level messages, but to coalesce them where reasonable to do so.

It's not hard to provide most of the other requirements of applications on top of the network-neutral low-level API we've defined. Application-level sessions can be provided on top of virtual circuits, and the virtual circuit ID mapped to an application-level session object at each end. A second level of protocol can give messages a named type, and a standard way of encoding the message contents (be it YAML or XDR or something else), and give responses to requests a header defining them as errors (with the body then containing fields identifying the error) or as successful responses (with the body then encoded appropriately).

Also, at this level, I felt I had to sneak in support for clustering. It's something the network itself doesn't need to support, but something that should be handled automatically for applications, so it had to go here. In the ARGON protocol used for application communications, [[ARGON|MERCURY]], I made the logical identifier of a service (to which messages, requests, and virtual circuit setup requests are sent) be a list of node addresses, a version number, and the identifier of the object within the cluster; when an application-level request is made, the protocol tries the nodes in turn until it gets a response, and includes the version number in each message, so that the replying node can include an up-to-date list of node addresses if the originating host has an outdated copy; I also made a third type of response message, which is a redirect, nominating a different node within the cluster that is better equipped to handle the request.

Again, including clustering at this level costs us little; an extra two bytes of header in the request to include the node address list version number (it can wrap after 65536 changes, since it'll be very unlikely that a client would be ignorant of precisely 65536 changes and then make a request with a version number that, although very out of date, is still identical to the one on the server... in fact, we could probably get away with a single-byte version number, but 256 changes is a little too close for comfort to my paranoid mind), and potentially larger responses when the cluster membership has changed. However, above this level lie a large number of different applications, and fitting knowledge of clustering into each and every one of them would be a lot of work.

Pages: 1 2 3

No Comments

No comments yet.

RSS feed for comments on this post.

Leave a comment

WordPress Themes

Creative Commons Attribution-NonCommercial-ShareAlike 2.0 UK: England & Wales
Creative Commons Attribution-NonCommercial-ShareAlike 2.0 UK: England & Wales