This site runs on Web server software called AOLserver. Haven’t heard of it? A lot of people haven’t. But they’ve probably been served pages by it. Apple.netscape.com, the default page on Apple’s Safari Web browser, is served by AOLserver 3.5.5. You can tell it’s AOLserver from the “.adp” extensions in the URLs. Other sites using AOLserver: AOL.Com, Mapquest, Digital City, photo.net.
I learned how to work with AOLserver back at ArsDigita. Once upon a time, back when most of the world was programming in CGI, philg built his business on AOLserver because it had an embedded, multi-threaded script interpreter and database connection pooling. Reasons you might want these are covered here.
Since then I’ve tooled around in lots of other environments. And each time I come back to AOLserver I kind of fall in love again. Embedded scripting and connection pooling may be old hat today, but AOLserver still sets itself apart from the pack in a few notable ways.
For example, most Web environments still don’t ship with an embedded task scheduler. The OSes can do it, e.g. Windows Scheduled Tasks and *nix cron, but the scheduled jobs run outside the server and therefore don’t have access to its apis or memory. This tends to add overhead when you want to run regular tasks that clear internal caches or talk to an application database. Of course you can still accomplish these things but it’s overhead and everybody does it in different, non-standard ways. Yuk. AOLserver programmers use ns_schedule_proc, ns_schedule_daily and ns_schedule_weekly.
Another thing that’s just wonderfully simple is database connectivity. When you want to pull database data into a Web script, you typically have to: a) fetch a database connection, b) define a query, c) assign parameters to the query, d) issue the query, e) fetch a row result, f) assign column variables in the local environment. Each platform has its shortcuts, but with few exceptions they still require 2x to 10x more code than AOLserver-powered OpenACS:
set title "Late Night With Conan O'Brien"
The colon syntax in “:title”, btw, ensures that the single-quote in “Conan O’Brien” doesn’t look to the database like a SQL string boundary, a well-known source of syntax errors and security holes.
A final nugget is the “master template” capability that Karl Goldstein and team programmed into ACS a number of years ago. This lets you define a reusable template in a single file, using a placeholder for the page-specific embedded stuff. Sometimes when doing layout, you want a bird’s eye view of the whole page. Master templates give you this, separate header and footer files don’t. Many scripting environments can do master templates, but last time I checked this was close to impossible in ASP.NET.
So I discovered not too long ago that Frontier can do all of these things too: task scheduling, simple db connectivity and templating. Database connectivity with Frontier is superlatively easy because all variables are db-backed by default. As Emeril would put it, Bam! Frontier can do a lot of other amazing stuff as well, but that’s a subject for a different post.
Anyway, if you use AOLserver, give it a hug today. It was a fabulous piece of software when AOL bought it from NaviSoft back in 1994 (ten years ago!), and it still is.
14 thoughts on “Have you hugged your AOLserver today?”
Its worth pointing out that AOLserver gets its power from the Tcl scripting language. Things that take many programmer-weeks in other environments are literally an eye’s blink in Tcl.
Also, several of AOL’s own properties are served by AOLserver, such as aol.com, some of the city guides, and there are many sites internet-wide that use it.
Long live the Mighty Mighty AOLserver, the greatest web server ever.
I’m a great fan of AOLServer (and ACS) but I have to disagree with a lot of what you’ve said. First of all, you’re unfairly mixing apples and oranges here. Some of the capabilities you’re touting are from AOLServer but many, many more are from ACS (an awesome infrastructure built on top of AOLServer – – at the cost of many programmer years of excellent MIT programmers).
It’s the infrastructure of ACS that provides that wonderfully simple database connectivity. In raw AOLServer, you still have to perform the six steps that you itemize.
Also, without the tremendous infrastructure design provided by ACS, you could argue that master templates are also close to impossible in AOLServer. Or maybe not, since when I copied the ACS design concepts in .NET, I found it pretty easy to implement master templates there.
I also don’t really see your point about scheduling tasks. .NET can easily schedule a job on the web server, the apis are available from everwhere, and I would argue that accessing your web server process memory with a scheduled task is both unnecessary in .NET and unwise if it can be avoided in general.
.NET and AOLServer are pretty much the same from my viewpoint with .NET having better tools and AOLServer having a better (and better yet, FREE!) infrastructure built on top of it. If you were to re-implement ACS in .NET, there is no question in my mind that you would have THE system.
Frontier does look interesting because of it’s object database. However, it appears to me (and this is only a semi-educated opinion) that there is a trade-off of design and development time (and flexibility) versus scalability which is beneficial for those sites which don’t need enterprise scalability (i.e. most) but which can’t be avoided. I would be VERY leery of trying to run anything which needed to support heavy traffic in Frontier.
I would also make the same time versus scalability comments about anyone who uses only the wizards in .NET but you can go back and recode the .NET for scalability as you need to later while you can’t give away the flexibility in Frontier to get back the scalability.
Mark, thanks for commenting! (and how are ya?)
I’m dying to know — can you point to the .NET apis for scheduling code on the Web server? None of our 6.171 students were able to find it last term.
Of course you’re right, I’m fudging a bit on the ACS vs. AOLServer distinction. Is this stuff really just as easy in .NET? My experience suggests no but I’d like to hear more.
I was able to write some shortcuts in .NET to make the database stuff *somewhat* easier, but there was still a lot of clutter due to the fact that .NET requires types and declarations for every variable. Every variable had to be converted from Object as it came out of the database, to String as it went out to the web browser, and vice-versa as variables came back in. How do you approach that? I know VS.NET simplifies some of this stuff, but it also makes the code a lot busier.
Also, I’d be really interested to see how you did the master template stuff. I gave it a try once. It was possible, but it wasn’t clean and felt like a gross violation of the ASP.NET team’s assumptions. Every Page wants to be at the top of the component tree. You can create parent/child classes, but then the parent has to get a bit funky with the child’s Components (assuming it can tell its own from the child’s). Maybe I missed something obvious. Is that written up in a form you could post or email me?
What I would like to know if I could add a LIMIT clause to the SQL example. Like
where title = :title limit :limit offset :offset”
I ask that because that has bitten me recently in some perl framework – on Postgresql the limit and offset should be bound as numbers, but the framework bound everythign as text. Usually this was not a problem since the database converted the strings to numbers, but not in the limit and offset case. This is the kind of problem that you can allways expect when you use a nontrivial framework.
Zbigniew, yes that is permitted.
Going back to Mark’s point about .NET having better tools. I’ve wondered about that. For the year that I used it daily, I spent a fair amount of time fighting VS.NET. It didn’t work the way I did, and, dammit, my way was right :-). Also, in my hands VS.NET didn’t scale well to large projects. It seemed to want to open everything at once which became unbearable as the file count went into the hundreds. When we tweaked our build setup to keep our projects in separate “solutions”, VS.NET had this annoying habit of locking .dll files larger than a certain size, so you had to close all other instances of VS.NET when compiling projects using the these large dlls.
I’m gonna do this as several pieces over the next few days . . . .
The way I did master templates (and skins) in .NET is similar to how we did the Country Gateway stuff at the World Bank with the following important notes:
1. Instead of being based upon a master tag, the master template is forced upon every page in it’s context (i.e. no one gets to avoid the template by pretending to be or actually being stupid).
2. The way skins are handled in several of Microsoft’s Quick Start apps is entirely bass-ackwards.
A simplistic view of my set-up is that I have one physical server with one ip address that is running multiple web sites off of the same code with different templates (look at
http://www.internationalpubmarket.com for the concrete example)
I hate hitting post instead of preview.
I hate hitting the comments hyperlink to check on one last detail of something you said and having it wipe out my incipient post.
I hate that I know better than to compose something complicated in a place where it can be wiped out and I still do it anyways.
Quick recap since I don’t have the time to redo it all again.
1. Create an IHttpModule that basically performs like the Request Processor in ACS. Have it determine which template it should be using and RewritePath to that template.
2. Have a control that, when included in the template, is a placeholder for your content (like the slave tag in ACS master templates). Have that control know how to pick apart the RawURL to find the name of the content file (the .ascx file). Have it know to search first in the subsite directory for that file, then the site directory, then in a default directory (or any other hierarchical search).
3. Also have that control able to take a sourcefile argument for when you want controls to appear inside other controls.
4. Use the Inherits= argument at the top of all your .ascx template files to get the correct code. Do NOT use the bass-ackwards method used in several of the Microsoft Quick-Start applications to apply skins.
5. Create an IHttpHandler to handle graphics and other similar files by pulling them from the correct directory based upon (sub)site. Ideally, this uses the same hierarchical search code that the Include contrl uses.
VOILA! You’re done. You can open up a new site simply by adding it to your hosts list. You can override your default templates one by one by adding new templates to the (sub)sites directory. If you’ve got an HTML-only coder, you can copy all the default .ascx files to the (sub)site directory so that they are accessible to him/her.
Regarding the apis for scheduling . . .
Heh. I’m going senile. I went back to grab the scheduling api code from my dispatcher . . . . only to find that it really is trivially simple to write your own scheduling routines (as in trivial enough that you apparently won’t remember doing it two years later and realize that you’re using your own functions instead of a standrd api . . . 🙂
What I’m doing is just using the database to store tasks and the timer api to trigger looking at the database. I’ve also got a lot of nice FileWatcher code and some nice locking code to prevent tasks that shouldn’t be run simultaneously from doing so.
I guess I can’t pick on you for confusing AOLServer and ACS any more . . . . 🙂
Regarding VS.NET scaling . . . .
What are your hundreds of files? Are they code files or template files? I’m not noticing any effect with template files but do definitely notice an effect after a while with code files. Much of this is because VS.Net is attempting to be helpful by effectively keeping ALL of your project code files open ALL of the time (notice how if you change the name of one of your often used routines by adding an x, your Task List window will immediately fill up with all the lines in all the files you’ve broken with the change).
Personally, I think that this is a good thing and that you shouldn’t be having this problem because I can’t imagine a code module with hundreds of files without breaking it down into separate modules. The dll locking problem is solved by putting dlls in a common directory a level above your project directories upon build (it only seems to want to lock dlls that are located within the project).
One thing which I really must say about .NET is “don’t fight it – – EVER!” If you don’t do things its way, it will make your life such a miserable hell . . . . My constant frustration is that there IS virtually always a good way to do something in .NET (a way where it is really simple) – – but it will always take you far longer than it should to find it. But, if you don’t take the time to find it, you are going to regret it later.
Re: master templates. So the RewritePath points to the master template, and the slave figures out what to do by looking at the request. Nice!
That’s actually very different from how it works in ACS, where IIRC the slave is processed first, and tells the request processor where to look for the master template.
Yes, it’s different but I didn’t want the control in the template programmer’s hands. I did do a version that worked like ACS but, as you say, it was incredibly clunky with all sorts of hierarchy and inheritance hassles.
Speaking of which . . . . Recently, I’ve been working with what I call post-forward. One of my biggest complaints with .NET has always been that when you post-back to a form and then redirect, you really can’t easily convey any variables (like the returnURL) with the redirect unless you keep them in the URL string. With a little work on my template class, I now have the universal functionality that the template can cause the postback page to do the postback process normally and then it clears it and builds the redirect page (and maintains the hidden state) without playing with either a Redirect or a Transfer. It makes a lot of sequential processes A LOT easier and once I figured out how to do it, it was actually pretty easy. I’m not quite sure why M$ didn’t include such a functionality in ASP.NET unless they just didn’t get around to it . . . .
Comments are closed.