Re: ANN: Etiquette: a protocol construction tool
Eugene Zaikonnikov <[email protected]> Wed, 17 Sep 2003 16:19:57 +0300
| Newsgroups | gmane.lisp.clump |
|---|---|
| Message-ID | <[email protected]> |
* "Luke" == Luke Gorrie <[email protected]> writes: Luke> Could you post some more details of how Etiquette works, and Luke> which particular programming aspects you are aiming to make Luke> easier? It would be extra nice to see examples of non-Etiqutte Luke> protocol implementations with pointers to the parts you want to Luke> make simpler. I believe that gathering communication-related code into compact and dedicated protocol descriptions gives benefits in debugging and maintainability. It should be easier to understand and modify an explicit protocol than one which is implicit and scattered throughout application code. Protocols, or parts of them, can be traced. Error handlers can also be specified on per-protocol basis, and even automated to some degree (e.g. out of band or invalid messages are reported by the framework). Underlying network transport can be switched without altering protocol body. Also, unified interface to protocols and communication transports allows to encapsulate application protocols into transports (for instance, SMTP, which runs over TCP, could be used as a transport for some other protocol. Or, SMTP itself could be run over a protocol other than TCP). Of course Etiquette is not a panacea. But hopefully, for certain tasks it could make life easier. Luke> I've been browsing the code a bit, let's see if I've understood Luke> it. It looks like use of macros such as: Luke> (defprotocol smtp-mail () (transfer request (:from :initiator) Luke> mail-request) (transfer-if response (mail-valid-p :from Luke> :respondent) reply-250 reply-550)) Luke> Expands into some code that updates data structures to Luke> understand a new state, and then these data structures become Luke> the input for execution engine that's essentially an Luke> interpreter. Is that right? Correct. The sequence of transfer forms results in corresponding PHASE objects being attached to the protocol object during initialisation. Each PHASE object encapsulates information about state transitions possible at this point, and during protocol execution this information is used to determine applicable actions and out of band messages. Luke> It looks like the machines get a stack, i.e. TRANSFER* will Luke> return after it is finished -- is that right? Etiquette protocols are mostly procedural descriptions ('mostly' because at the moment it is possible to transfer control from protocol error handlers). Phases (the transfer forms) are executed sequentially; if a subprotocol was invoked, current protocol execution will resume after its completion (unless communication was explicitly terminated in the subprotocol). Luke> Is the :from :initiator/:respondent there to distinguish Luke> between things done by the client and the server, such that a Luke> single protocol description defines both sides? Exactly. Protocol describes communication between the roles. During instantiation, one have to specify the role in which this protocol object is intended to be executed. I moved away from 'client' and 'server' terms though, in favour of 'respondent' and 'initiator' as role designators, since I found them confusing on several occasions. Incidentally, BEEP framework developers seem to choose exactly the same terms, so this was probably a right move. Luke> Also, I'd appreciate a couple of sentences of comments for each Luke> of the major data structures, saying what they're for and how Luke> they relate to each other. You may want to look at the section 3 of design-notes.txt (it should be in the tarball). The document outlines the data structures employed. But in short, there are five major classes: - INTERACTION-PROTOCOL, that represents, well, an interaction protocol - PHASE, encapsulating state transition data for each protocol phase - COMMUNICATION-AGENT, mainly used to tie protocol with application logic - COMMUNICATOR, that handles actual data exchange for a protocol and its subprotocols - TRANSPORT, which wraps specific communication transport Now, every INTERACTION-PROTOCOL has a number of PHASEs and a COMMUNICATOR that it shares with its subprotocols. COMMUNICATOR talks to a specified TRANSPORT. Each action and conditional test method is specialised on protocol, its role (via EQL specialisers) and a communication agent. This allows to flexibly mix agents (e.g. if one wants an HTTP proxy, they could inherit from a server agent and a client agent). If you'd like any clarifications, do not hesitate to ask. Luke> here's what I'm looking for in a framework like this: Luke> Multitasking. One thread should be able to run many state Luke> machines, so that when one blocks on I/O another is allowed to Luke> execute. I don't quite understand how can execution proceed in the same context when blocking input operation is performed. Could you please elaborate on that? Maybe an example where that would be useful? But in general, I see no obstacles to using Etiquette in multitasking environment. It's just that managing multitasking itself is outside of scope of the project. Luke> Complete. Either general enough that I can _easily_ extend it Luke> for "weird" unanticipated cases, or complete enough to Luke> anticipate everything. Etiquette is by no way complete. It was mainly intended to make writing new protocols easier; however, it became apparent that with relatively little additional work I can extend it to support a number of existing protocols (via detectors and aggregators). Still, there are protocols around that are tedious to implement in Etiquette. Hopefully its applicability will extend gradually, but I refrain from grand claims on completeness or generality. Luke> Some protocols have special requirements -- e.g. considerable Luke> state that is abstracted out of the state machine description, Luke> or complex timeout logic. Agents can be good places to store application state not directly related to communication. Also, second argument to defprotocol is intended to contain auxiliary info not directly related to state machine (error handlers, transport specifiers and such). It shouldn't be too hard to extend the list of allowed options. As for timeouts, I think finer-grained control is needed. E.g. SMTP RFC suggests various timeouts for various stages of protocol, hence per-phase timeout control should be provided. Luke> I may also e.g. need flexibility in how I parse my input Luke> depending on the current state. Aha.. I hope this can be reasonably done by specialising detectors/aggregators to protocol and state designator. If this will work out, it'll get into the next release. Luke> Protocol encoding. Some nice libraries for parsing/printing Luke> protocol messages can go a long way. Frode Vatvedt Fjeld's Luke> `binary-types' package is a superb example of such a library Luke> for bit-packed protocols like the lower layers of Luke> TCP/IP. Something for handling ASCII protocols like Luke> SMTP/POP3/HTTP with similar ease would be just great. (Gilbert Luke> Baumann is doing some nice stuff for lightweight lexing/parsing Luke> -- maybe something for this?) It is a crime for messages Luke> specified by context-free grammars to be parsed ad-hoc in a Luke> language like Lisp. Doubly so when you have to worry about Luke> avoiding blocking on I/O. Thus far, Etiquette performs encoding/decoding only to extent necessary for proper state identification. Message contents are defined by particular applications. I agree that content encoding is important, but not so sure whether it should be addressed by Etiquette or left for choice of application implementor. But if that sounds like a reasonable extension to people, I'll look deeper into that. Luke> I'm guessing that to really get this stuff right requires Luke> implementing at least a dozen protocols. Some friends did a Luke> framework along these lines for Erlang, called the "bit Luke> syntax". They spent a year implementing every protocol they Luke> could think of from the internet and telecoms world, extending Luke> and refining it as they went along. The result is very nice, Luke> and by all accounts it was great fun :-) My approach is similar: implementing various protocols to find and polish the rough edges of the framework. Naturally, there still many issues left; however, am coding it alone, in my free time and for only three months, so I hope for leniency :) Luke> Anyway, I know a few links that might be interesting to you: Thanks! I'll definitely look into that. -- Eugene