Measure Twice


If there were a theme for my first two weeks as an Outreach Program for Women intern, it would be tutorials. As my project, I’m maintaining the mail portion of Twisted, an event-driven, networking framework in Python. I’ll be working to improve the documentation, make progress on partially completed tickets, and attack some new defect and enhancement tickets. Up until now, I had used several aspects of Twisted in a project and submitted a couple of patches, but I hadn’t used the mail subproject and wasn’t familiar with any of the mail protocols that Twisted supports. Working through the mail example code and tutorials seemed like a good introduction and would allow me to evaluate how well the documentation meets the needs of new users. Further, there were a few outstanding tickets related to documentation that I’d be able to work on straightaway.

I found immediate success in running the examples of clients that use the IMAP4 protocol to access email from a remote server. I was also able to run a simple email server that uses SMTP to receive messages, although I had to read the source code to figure out from which address it would accept messages. When it came to the examples of clients which use SMTP to send messages, nothing worked.

SMTP is a text-based protocol in which a client issues a series of commands and receives replies from a server in order to send mail. To investigate the problem with the SMTP client examples, I thought to use telnet to connect directly to the email server and issue the commands manually. Not only couldn’t I connect with telnet to the servers used in the examples, I couldn’t even connect to a Google server. In all of these cases, I was attempting to connect on port 25, which is the well-known port for SMTP. My OPW mentor, Jessica McKellar, theorized that the problem was caused by my ISP blocking outbound traffic for port 25. Verizon’s website confirms that they do this to prevent virus-infected computers from sending spam.

With this problem in mind, I moved on to the tutorial on how to build SMTP clients. I ran into the same problem that had earlier prompted a trouble ticket. The tutorial requires a server running on port 25 of localhost but it does not explicitly mention this requirement nor does it give directions for running such a server. A patch had been submitted to explicitly mention the requirement and suggest that the user could change the example to use an external SMTP server. A review of that patch had found no problem with the change in wording. The review, however, raised an ancillary issue, noting that the output listed in the tutorial did not match what was actually generated by running the examples. This same complaint was documented in another open ticket.

I wasn’t satisfied with the proposed solution, since the user might well be blocked from contacting an external server on port 25. I thought the best solution might be to include directions on running a server locally, to be used with the tutorial. With my limited knowledge of Twisted mail, I modified the example SMTP server to run on port 25 and accept mail from any user. There were some quirky requirements involved in running this server, but I was able to get through the tutorial with it.

Although I had gotten the tutorial working with a local server, I suspected that my solution might not be the most elegant. Rather than submit a patch and upon review learn of a better way to solve the problem, I thought it prudent to consult with the Twisted developer community on the twisted-dev IRC channel. I learned that I could use the twistd utility to start up a mail server with its configuration, including the port, specified through command-line flags.

When I mentioned that I planned to update the output listing in the tutorial in response to both tickets, one developer suggested that was futile since the output would vary based on release and platform and that it would be better just to mention in the tutorial that the listing was representative. He then closed the second ticket, explaining why it wouldn’t be fixed.

In the discussion, one of the developers asked me to amend the first ticket to summarize the problem and specify the completion condition. I specified that the solution was to make the tutorial self-contained so that a user would need no external knowledge to work through it. Then I revised the tutorial to make it so. At the same time, I fixed some issues of formatting, punctuation, grammar, clarity, and accuracy.

Before I could submit a patch, I needed to build the documentation. Similar to the process of building code, tools must be run on the raw form of the tutorial to produce nicely formatted output. Twisted includes a documentation generator tool called lore which translates XHTML input with annotations to indicate, among other things, links to API documentation and code listings into HTML output.

My patch received a quick review. In addition to some requests for minor changes and clarifications, the review included some comments which seemed to suggest that the examples used in the the tutorial might not best represent how to write an SMTP client. I was concerned because the ticket was currently limited in scope to making the tutorial self-contained. Changing the examples, while possibly an improvement, would require significantly reworking the tutorial. In the IRC channel, I asked for confirmation that this was what was being suggested and if so, should it be done as part of the same ticket. The consensus was that the suggestion constituted scope creep and should be addressed in a separate ticket. Now, I am left to submit a few minor revisions to hopefully close out the ticket.

If that weren’t enough in the way of tutorials, I also tackled a new tutorial on building SMTP servers. Comments had been sitting in the ticket for nine months. In addition to incorporating the comments, I edited the document and modified the presentation of some examples to hopefully make them more clear. I found the final example, which is meant to explain how to use the IMessageDeliveryFactory interface, to be lacking and wrote a new example to better showcase it. The changes are nearly ready to be submitted.

Work on these tutorials will continue but my focus is now turning to another area of documentation – the API. More on that to come.