Line: 1 to 1 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
Deleted: | ||||||||
< < | Ducky 511 Progress Report | |||||||
Changed: | ||||||||
< < | CGI
PLT web-server
| |||||||
> > |
CGI vs. PLT web-serverAbstract@@@ CGI old and hoary, page-oriented; PLT new and whizzy, does cool things The goal of this project was to evaluate PLT web-server in the context of an actual application, and to compare that experience to my past experience of developing with CGI. In particular, PLT was advertised as:
Related workTo-do list managersFor this project, I developed a prototype of a to-do list manager. To-do list managers have proliferated widely. Radicati recently reported that two groupware tools with integrated to-do list management, Microsoft Outlook and Lotus Notes, are on track to have 126 million and 88 million users, respectively, in 2005[1]. Personal Digital Assistants, like those from Palm and Blackberry, will have sold approximately 15 million units by the end of 2005[2]. However, Bellotti et al[3] found that few people actually use electronic task management tools, preferring instead to use post-it notes, index cards, notebooks, electronic mail, and calendars to manage their tasks. In their study, they found that only 6.7% of to-do items were logged in to-do applications. While I have not found research to support or refute it, I believe that electronic to-do list managers suffer from an overabundance of information. Tasks that cannot (or should not) be started yet can crowd out more immediate tasks.ToolsCGICGI, the Common Gateway Interface, was developed by Rob McCool [CGI@@@] in 1993[CGIlist@@@] to aid development of dynamic web content. It is conceptually extremely simple:
PLT web-serverThe PLT web-server, by contrast, is very stateful. Each page is a new continuation; in practice, moving from one page to another corresponds to a calling a procedure. State is held in global variables or parameters passed from function to function. (In reality, some state information is held in URLs in the user's browser, but that is almost invisible to the application developer.) @@@ references, related work This has several implications:
ImplementationI developed a prototype of a to-do list manager using PLTWS. While there are not many web pages, there are a lot of interactions between state variables in interesting ways. The main page of the application is the list of tasks, as shown in Figure 1. (showEverything.gif) In Figure 1, all tasks are visible in the top portion. Under the tasks is a text box for adding tasks, and below that are controls for hiding and showing tasks based on several different criteria. Tasks can be "deferred", as shown in Figure 2 (hideDeferred.gif). After "Hide deferred" is clicked, all tasks whose "hide-until" date are later than the current time are hidden. When deferred tasks are visible (e.g. the "Show all deferred" link has been clicked), they have "Undefer" next to them instead of "Defer". Tasks that have been completed have a strike through them. Completed tasks can be hidden by clicking on the "Hide completed" link, as shown in Figure 3 (hideCompleted.gif). Tasks which can be acted upon -- ones that do not have pending subtasks and which are not yet completed -- have a "Done" link at the end of that line. Clicking on the "Done" link puts a strike through that task and removes the "Defer" and "Done" links. Tasks that cannot be acted upon can be hidden by clicking on the "Hide all supertasks" link, as shown in Figure 4 (hideDependents.gif). Note that a blocking task is still indented, reminding the user that other tasks depend upon its completion. When all of a blocked task's subtasks are done, then that task becomes active: "Done" and "Defer" appear next to it, and if it was hidden by "Hide all supertasks", it becomes active, as shown in the sequence shown by Figures 5, 6, and 7. (doneFirst.gif, doneSecond.gif, doneThird.gif) Notice that some tasks are displayed with different saturation: tasks with higher importance are less saturated and hence more visible. Clicking on the short task description allows the user to see more detailed information about the task, and to edit it, as shown in Figure 8. (editPage.gif) A briefer page allows the user to defer the task in a similar way, as seen in Figure 9. (deferTask.gif) @@@ more about code struture hereResultsTool ecosystemThere were a number of significant areas where CGI's greater longevity and popularity made it much more compelling than PLTWS. The ecosystem surrounding CGI is much more abundant and mature. This is perhaps not PLTWS's "fault" -- CGI had a @@@-year head start -- but it is a reality which indelibly colours the experience of using PLTWS or CGI.Documentation.Finding good documentation -- including example code -- was a major issue. CGI is very wide-spread, well-documented, and -- because it is conceptually so simple -- easy to explain. PLTWS is harder to explain and has much less documentation. I spent a lot of time trying to figure out how to do things. One example of a lack was so trivial it was quite depressing. I was having trouble tracking down a bug; it was clear that there was something I was not understanding, and one of the areas that I didn't understand was the difference between send/suspend and send/suspend/callback. I looked all over for information about the difference, and finally asked a Scheme guru with whom I had a personal connection. He told me that the differences were so minor and buried so deep in the implementation that I didn't need to worry about it. This allowed me to stop wasting time on that blind alley; had I not had access to a guru, I would have spent even more time for wont of better documentation. There was also an issue which might have been documentation or might have been a bug. While normally in HTML, tags have attributes in the form foo="bar", radio buttons and check boxes have an exception. To specify that a radio button or checkbox is checked, the developer must specify the attribute "checked" without a value. I could find no way to specify an attribute without a value. I tried to drop down into raw HTML text, e.g. <input name="foo" checked> but found to my dismay that the server helpfully escaped the metacharacters for me. I did eventually find a workaround, but it is fragile. It depends upon the browser treating checked="true" the same as checked. While Firefox exhibits this behavior, it is not guaranteed that other browsers will.InfrastructureIt is normal for web hosting services to provide access to CGI and Apache. Conversely, it is not normal for web hosting services to run PLT web-server. While my web hosting provider (Dreamhost) originally said that they would allow me to run PLTWS, they later reversed themselves.InstallationWhen I tried to install PLT on Dreamhost, the binary installation failed. Building from source, I got different failures, which I didn't get debugged before Dreamhost told me they would not allow PLTWS to run. Widely-used tools evolve to deal more gracefully with different configurations. Simpler implementations are easier to build.PersistenceI heard the buzz about how PLTWS took care of persistence and (perhaps naively) thought that meant that state was automatically stored to the file system. It does not. This means that the server needs to store valuable data (like credit card numbers) every time that data changes, which is not so different from CGI's requirements. It does mean that it is easier to deal with "the back button" problem with PLTWS. It is relatively common to have situations where the user does something to make the server perform some action which is difficult to reverse and which should not be done twice. (Examples include charging a credit card or deleting the current record.) With PLTWS, it is trivial to prevent a user from hitting the back button: simply use a send/finish call in place of a send/suspend/callback call. When using CGI, the server must keep two a persistent token representing the client's position in a transaction, and give the client a matching token. Then, at crucial steps, the server must compare the server's token with the client's token to ensure that the client is not trying to perform an action out of sequence.SecurityPLTWS and CGI each have advantages and disadvantages in the security arena. CGI can be easily used with https, while the only well-documented method for using PLTWS with HTTPS is a complicated method involving a proxy server.[Cookbook] At the end of that web page, there is a suggestion for how one would approach the task of making PLTWS work with HTTPS, but there are not step-by-step instructions. This might be yet another documentation issue. On the other hand, PLTWS is clearly superior to CGI in some ways.
Memory leaksPLTWS processes live for much longer than CGI processes, they need to manage memory more carefully. Furthermore, because PLTWS maintains state for visited pages (so that the user can go back and choose a different set of pages to traverse), PLTWS has a built-in memory leak. To work around that, PLTWS allows the developers to set an expiration time on pages. Unfortunately, the error message that greets users when they come to an expired page is absolutely identical to the error message they get if a page never existed. I observed that I and another were both quite confused -- even distressed -- when pages "disappeared".DebuggingCGI has not traditionally been the easiest system to debug, but PLTWS is worse. In both cases, text that normally goes to standard error goes off into unintuitive places. With CGI/apache, it goes into an error file, usually under /var/log, with restricted read access. Libraries[Carp] also exist that will redirect error messages from stderr to stdout (and hence to the browser window). With PLTWS, the documentation claimed that it would go to a log file, but I couldn't find any such log file. Instead, the errors went to the terminal window where the server was started. Particularly if PLTWS is running on a server in a data center, this is less than useful. Finally, while most systems have somewhat cryptic error messages, I found the PLTWS messages to be particularly cryptic. For example, sometimes there were line numbers in the error messages; sometimes there weren't.Modularity and code structureOne of the benefits touted for PLTWS was the ability to operate at a procedure-per-page level. The biggest benefit that I found was in not having to encode and decode all the state information. In particular, it was very nice to be able to pass around a task instead of the task's UID. While encoding/decoding the UID itself is not very difficult, finding the task that corresponds to that UID was trickier. (I was in the middle of debugging exactly such a procedure when I slapped my head and asked myself, "Why am I doing this?" It was a joy to pass the task around directlyinstead.)User interface issuesIn the course of the project, I changed several things in the user interface design as a result of either technical complications, UI difficulties, or UI opportunities. First, I had expected (perhaps naively) PLTWS to handle persistence for me. I decided not to expand the scope of my work to include attaching to a database because
Speed@@@ dependsFuture workI would like to redo this application in Javascript, as I believe Javascript has many of the advantages of both with relatively few disadvantages.
Parting wordsPLTWS and its associated libraries, in general, do a very good job of abstracting away the details of transferring state information around a program. This is good, but when implementing abstractions, particular care must be taken that they are not leaky abstractions as described by Joel Spolsky [LeakyAbstraction]. The Scheme library attempted to hide the messy details of how checkboxes and radio buttons are described in HTML, but in doing so, kept me away from tools I needed to declare a button/box checked. PLTWS also abstracts state persistance. While this is nice in theory, it is not a perfect abstraction because it does not persist information across server restarts. "Model information" needs to be explicitly persisted, and "view information" will be lost. Working on this project, I sometimes felt like I was living in an exquisitely beautiful mansion which automatically adjusted the lighting for me and got it right 99% of the time -- but 1% of the time I needed the lighting to be something different, and the controls were hidden away so discreetly that I had a really hard time finding them to override the system. (And of course, the mansion had an inadequate users' manual.) Visible light switches might be ugly, and might be annoying to have to operate all the time, but I always know where they are.@@@ Thanks to Christopher Dutchyn, Jim DeLaHunt. References [CGI] Rob McCool, The Common Gateway Interface, http://hoohoo.ncsa.uiuc.edu/cgi/overview.html ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | |||||||