Archive for the '.Net' Category

Ajax: Seaside vs .Net

One thing I want to mention that might go unnoticed otherwise, is the difference between how things are done in Seaside vs. .Net. .Net, specifically ASP.Net, is based upon the concept of server controls. .Net’s Ajax framework, Atlas, can allow some things to be done in just as little code as in Seaside, declaratively. But there’s an inherent difference, philosophically, that’s reflected at every level, all the way down to the language.

.Net is based upon pre-designed controls, that have very specific capabilities, step outside the bounds of those capabilities, and you’re on your own, everything gets very hard. Seaside and Scriptaculous reflect the opposite approach, you build solutions by simple composition of existing components, there is no limit to how you can wire things together, except your imagination.

This is the same philosophical difference between the languages, Smalltalk is open, you decide what the language is, while C# and VB.Net are closed, the compiler writer chose the languages capabilities for you. If what you need to do fits within the limited of scope of what .Net’s server controls offer, you might find it quite capable and enjoyable to use, but it can’t compete with Seaside when you need to come up with a unique solution.

This is where Smalltalk and Seaside shine, they don’t limit you, you can compose any solution you need, simply and easily. You don’t need pre-built components because it’s so easy to create them, on the fly, whenever you need them. If you find yourself doing the same thing over and over, you can create a component, or extend the renderer to make it simpler. In the previous article, I created cascading dialogs, but I didn’t do it by using a control that was built with those capabilities. I simply composed a solution out of generic parts, .Net can’t do this.

Running Seaside, Apache, and IIS on One Machine

Coming from the .Net world, I have many projects I have to support that require my machine to have IIS (Internet Information Server) installed. Though Seaside is now my preferred development environment, and Apache my preferred web server, they need to all co-exist for me to do my job.

Seaside’s web server isn’t built for handling the kind of load Apache and IIS are capable of, and there’s a lot of things a web site needs to serve up besides dynamic pages. Offloading all the static content, images, Javascript, CSS, HTML, zip files, and any other large downloads, is handled much better by a battle tested web server like Apache or IIS.

So the question arises, why use Apache at all, why not just use IIS? The answer is quite simple, IIS sucks for anything but using ASP.Net; it’s not a pluggable web server like Apache is. When I first started using Seaside, I tried to get IIS to reverse proxy for me, it was a no go, I’d have to write code. Reverse proxying isn’t something IIS can do out of the box, yet it’s a simple configuration change in Apache. Apache has far more capabilities as a web server, than IIS does, or ever will. So I bit the bullet and learned how to use Apache, and I’m glad I did, it’s an awesome web server.

Problem is, web servers want to run on port 80, so which one gets to own that? You’d think that you could easily run them both on port 80, and bind them to different IP addresses. In fact, this is possible, but it’s a royal pain in the ass to accomplish, because IIS isn’t well behaved and grabs onto whatever port it’s running on, on every address on the machine, even when it isn’t configured to do so, preventing Apache from being able to bind. There are instructions out there, on getting IIS to behave, but I gave up, it wasn’t worth the effort.

Apache on the other hand, behaves perfectly, and does exactly what you tell it to do. Apache also supports reverse proxying out of the box. Given these options, I decide to run Apache as my primary web server on port 80, and run both IIS and Squeak on other ports and use Apache to simply reverse proxy to them both. This configuration works great. I went into my IIS sites in Internet Service Manager, changed each site to bind to port 81 instead. In Apache, you’ll need to edit the httpd.conf (equivalent of Internet Service Manager) and bind to the local address on 80…

Listen 127.0.0.1:80

Uncomment the following (I think they already are, but don’t recall)…

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so

Enable virtual hosting…

NameVirtualHost *:80

And then create a virtual host, this is where all the magic happens

<VirtualHost *:80>
    ServerName localhost       #bind hostname, could be onsmalltalk.com for example
    RewriteEngine On             #enable url rewriting
    ProxyVia Block                #enable reverse proxy
    ProxyPreserveHost On     #make proxy rewrite urls in the output
    #for each .Net app, add a rewrite rule to intercept and proxy it
    RewriteRule ^/DotNetApp(.*)$ http://localhost:81/DotNetApp/$1 [P,L]
    #only allow Seaside rewrite rule to fire, when request doesn’t match an existing file
    RewriteCond C:/Inetpub/websites/%{REQUEST_FILENAME} !-f
    #if no file was found, proxy the request to Seaside
    RewriteRule ^/(.*)$ http://localhost:90/seaside/someAppName/$1 [P,L]
</VirtualHost>

Which looks much simpler without all the comments

<VirtualHost *:80>
    ServerName localhost
    RewriteEngine On
    ProxyVia Block
    ProxyPreserveHost On
    RewriteRule ^/DotNetApp(.*)$ http://localhost:81/DotNetApp/$1 [P,L]
    RewriteCond C:/Inetpub/websites/%{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ http://localhost:90/seaside/someAppName/$1 [P,L]
</VirtualHost>

And that’s it. Apache now acts as the front end, enabling the seamless appearance of running all the web servers on port 80. Visual Studio fires up and binds to .Net web sites without a hiccup, none the wiser that Apache is proxying the request. Mod rewrite now allows me to pick, based upon anything in the URL, which web server needs to handle the request. .Net sites run great, Apache handles all the static content, and Squeak only receives requests for dynamic page generation. Apache can also handle all the SSL requirements, certs, and leave Squeak blissfully unaware that the client is connecting through HTTPS. I use essentially the same setup in production.

Seaside, ODBC, and Sql Server for the .Net Developer

The first thing any .Net programmer wants to know, after finishing the toy examples, is how do I connect to Sql Server and do some real work with Seaside.

Yes, I said Sql Server! No other database is in wide use in the .Net community. No one, and by that I mean very few, uses MySql, PostgresSql, Oracle, FireBird, or any other database you can think of. 90% or more .Net programmers use Sql Server exclusively, it’s just what’s done. I’m not against other databases, or object databases, and have used Goods and MySql a bit myself, but if Squeak and Seaside want a foothold in the .Net community, it must play nicely with Sql Server, PERIOD!

This is a problem, a huge problem, because Squeak doesn’t have native Sql Server drivers. Squeak’s only access is via ODBC, which uses Squeak’s Foreign Function Interface (FFI). ODBC works reasonably well, and seems reasonably fast, however, the FFI locks the VM when in use effectively making all access to Sql Server single threaded. Yes, some of these other database have native drivers that don’t lock the VM, but I’m not talking about them. Yes, you could use Visual Works and Seaside, which has native access, but I’m not talking about it either. I’m only talking about Squeak and Seaside, I prefer them, because they’re free.

In Squeak, it’s ODBC or nothing, and ODBC simply can’t scale. You can do small sites in it, but tying a multi-threaded server, the web server, to a single threaded interface to the database (FFI), simply can’t work in production if you expect any sort of heavy load. It’s unacceptable to have one web request waiting for another to finish a query, while blocking the user.

Now, this might seem like a show stopper, I almost thought so myself, but it’s not. If you set your architecture up right, you can avoid the need to access Sql from Seaside, and avoid the issues that ODBC and FFI create. You simply have to change your approach, and consider Seaside as an addition to your existing .Net infrastructure, rather than a replacement.

If you have a site large enough to be too big for ODBC, there’s a good chance you’re going to have multiple web servers load balancing the traffic. If you have a site large enough to need to load balance the traffic, there’s a good chance you may have already broken your application up into tiers. This is the perfect place to combine the strengths of Squeak and Seaside, with the strengths of .Net.

Break your application up into two tiers, a presentation tier, and service tier. Have the service tier consist of .Net based web services, and the presentation tier consist of Seaside based sites that consume those services via Squeaks SoapClient library. You can host the application tier, on the same boxes as the web servers, or on their own boxes, if you have the traffic to justify load balanced application servers as well.

SoapClient has recently been made compatible with .Net after I did a little begging and pleading with the author, Masashi Umezawa, to make a few changes to accommodate .Net’s quirks. He was totally cool, and made the necessary fixes in less than a day, I can’t thank him enough.

.Net is perfectly sufficient, and actually quite nice, for running queries against a Sql Server database and handing it out via web services. .Net’s weaknesses lie in its poor web framework. I shouldn’t even say poor… from the Seaside point of view, it’s simply old fashioned. If you think of Seaside as just the presentation layer, which it excels at, you’ll find it quite a nice division of labor. .Net can hand back real objects to Squeak, which can use them quite easily, either as dictionaries of associations, or if you register a real object with SoapClient, can de-serialize directly to a real business object containing all the necessary rules biz objects contain.

You also gain the benefit of forcing yourself to create services that you will likely find other uses for. Maybe you have other clients who’d like access to those same services. Maybe you can take advantage of this architecture to have your .Net guy building web services while you Seaside guy plugs away building the front end. Your Seaside guy can fake the services and build the front end while he’s waiting for the real ones to be build, should that be necessary.

Be careful when using SoapClient against a service, there are some security issues with Squeak’s SoapClient. Make sure you control the server, and trust all data coming from it, else someone could execute arbitrary code in your image by returning some bad data. For the same reason, I wouldn’t host any web services in Squeak, I’d use .Net, or whatever your favorite provider is. But for accessing in house web services, that you trust, I see no problems using Soap as the leverage point to introduce Seaside and Squeak into the world of .Net. Seaside royally kicks ASP.Net’s ass, and can make building your web applications an order of magnitude faster and easier, and that counts for a lot.

I’ve been using this approach for a couple of months, and so far, it’s working quite well. I will continue doing so, and write about any issues I run into, as I run into them. In the mean time, I’d love to hear from anyone doing anything similar.

Seaside for the .Net Developer

When I first started using Seaside, it took me a while to shake out a few misconceptions that were holding me back. Many of the things I’d learned to do in .Net were no longer necessary, Seaside was different, and I had to shake some old habits before I finally grokked it. I’ll use this blog to try to explain a few of them, as time permits .

First thing; State. .Net pages are stateful, but in a different manner than Seaside. .Net, in an effort to emulate desktop development, created the concept of viewstate, which was in essence nothing more than a hash table that was automatically serialized and deserialized into a hidden form element, something developers used to do by hand.

Server controls, stateful UI widgets, were then able to save and restore their state into this hidden field on each postback, giving the illusion that a page maintains its state between postback, and removing from the programmer, the hassle of thinking about request.form and repopulating form fields on each postback. This was often done by hand in classic ASP by having the value of a field be equal to its request.form value, which is where the concept of a post back originated.

The viewstate abstraction, while useful, leaked, as all abstractions do. .Net pages are classes, and like any class, can have member variables. However, only “server controls” remembered their state, and only because their authors utilized viewstate to do so. One cannot simply assign a member variable and expect it to still be there after the next request. For value objects, one could simply store the object directly in the viewstate hash, but for reference objects, developers got in the habit of storing id’s to the objects they needed, in the viewstate, and then on each postback, an accessor would fetch the object using the id, allowing the illusion of a stateful page.

Storing id’s and passing id’s around in query strings and cookies, isn’t very object oriented. Problem is, the developer had to wire this plumbing up manually, each time he needed it, it was more of a design pattern than a framework.

.Net, like Seaside, has sessions, and can store objects in that session, but unlike Seaside, each time a page is viewed in .Net, a new instance of it is created, and its state is restored from the previous instances viewstate. Pages never lived longer than the current request. All of these issues, and hacks, are a symptom of a core problem, pages aren’t stateful. No matter how much you want to pretend the web is stateless, it really isn’t. If pages aren’t stateful, you have to manually fake it.

This is where Seaside’s first big conceptual difference lies, Seaside components, the equivalent of .Net pages, are not only stateful, but can have a lifetime equal to that of the current session. Each time you view a page from Seaside, you’re viewing the exact same instance that was initially created when you first entered that page. This has quite a few advantages.

Instance variables are not lost between postbacks. For example, if you set an instance variable equal to a customer object, that customer object will stay there throughout the entire user session, you need not ever fetch it again, or hold onto its id, or even think about state. This is exactly how you’d program a standard WinForm application.

Seaside components are also objects themselves, when you create a component, you create it, not the framework. This means you can use constructors, and pass any necessary state directly to the component. In .Net, this isn’t the case, the framework creates the page for you, and you read in necessary state from the query string.

Let’s say your going to edit a customer object, and you’re on the search page, in .Net, you’d write something like the following in a databinding method for a link server control to setup a url to link to the detail page…

aLink.Url += customer.Id;

or a more older style redirect to the detail page…

Response.Redirect("CustomerDetail.aspx?id=" + customer.Id);

and on the detail page on each postback of that page, you’d have to re-fetch the customer with something like this…

Customer customer = Customer.Find(Request.QueryString["id"]);

But you only have to do this, because pages aren’t real objects, and can’t remember their own state. In Seaside, you don’t redirect to a new page with an id in the query string (you could, but it’d be stupid), rather you write the link like this…

html anchor
    callback: [self call: (CustomerDetail for: customer)];
    text: ‘edit’.

When the link is pressed, a detail control is created, and simply handed the customer object directly via its constructor. The called component simply replaces the calling component in the UI. The calling component, though not visible, stays alive waiting for the called component to return. Simple, elegant, and exactly what you’d do if you were writing a WinForm application for the desktop. What Seaside does for you, is take the code in the callback block, and create a continuation, a unique link pointing to it, and writes the URL to the anchor tag for you. It simply automates what you have to do by hand in a .Net web application.

Understand this one thing, will help you tremendously when attempting to write a web application in Seaside. I wasted a lot of time trying to figure out how to set and read query strings and form posts and assign urls to anchors, because that’s what I was accustomed to doing. If you want to try Seaside, you’ve got to drink the cool-aid deeply, accept its idioms, and get on with getting the job done. Seaside is “truly” object oriented, .Net simply pretends to be, and then punishes you when you actually try and program in an OO fashion.