Heh.Mark Barker noticed that mySMTP transport implementation also supports request/reply MEP’s andcomments (in his usually contrarian fashion) that SMTPwas one-way for a reason.
Layering two-way communication over a fundamentally one-way transports is areally common pattern. People do this all the time over SMTP – the numberof mails in my inbox that have subjects starting with “RE:” istestament to that.
Request/reply is a very useful (and prevalent) abstraction. Most applications(including HTTP) are built on a request/reply pattern. Sending a message,receiving a response, and being able to match up the request with the responsein some way is a useful thing. The problem with request/reply is that it often assumesa degree of temporal coupling that doesn’t strictly have to exist.
What do I mean by temporal coupling? It’s the assumptions you make abouthow long it will be before you get the response back. A lot of R/R is done overthe backchannel of a duplex transport like TCP – which couples thetimeliness of the response to the lifetime of the connection that sent theoriginal message. When we think about request/response as a MEP we oftenimplicitly assume “request/response in a reasonably small amount of time”.However, from a MEP perspective, request/response is still request/responseeven if the response comes hours or days later over a completely separatenetwork connection.
To be fair, most networking stacks (including Indigo, at the moment) don’texactly address this issue of temporal coupling because they maintaincorrelation state in memory. All the goo that’s used to match upresponses with requests is stored in-process, which couples the timeliness ofthe request to the lifetime of the currently executing process. Furthermore, alot of apps call request/response MEP’s using the local metaphor ofsynchronous method invocation. This pattern effectively ties up a bunch ofapp-level correlation state and stores it in the callstack of the thread thatsent the request – implying that the same thread must hang around untilthe response comes back. This puts a drain on system resources and decreasesoverall scalability. As a result, today its best to implement temporallydecoupled R/R messaging explicitly as a sequence of one-way messages. Thisapproach just punts the issue of correlation up to the app level, making you doa lot of work that should rightly be handled by the infrastructure.
SMTP is an interesting platform for thinking about request/response because it requiresa large degree of temporal decoupling to work well. Ideally, you’d liketo be able to initiate a R/R MEP asynchronously, persist all of you app stateto disk, reboot the machine six times, and have the code be able to pick up exactlywhere it left off when it eventually receives the response. SMTP/Mail offers arobust store-and-forward infrastructure for keeping message around until you’reready to retrieve them, but work still needs to happen on the infrastructureside to make sure that there’s a receiving party around capable ofprocessing the response.
Soyou can look at the R/R support in the SMTP transport as something of anexperiment. The network characteristics of mail violate pretty much everyassumption we make about the behavior of request/response messaging, whichmakes it an interesting topic for further study. I generally like things thatviolate assumptions because they do a good job of exposing what you’reassuming…
