Archive for the tag 'Programming'

My Journey to Linux

I’m a Windows guy, I’ve always been a Windows guy. Windows today is more stable than ever. Seems now would be the best time of all to be a Windows guy. Slowly but surely though, I’m becoming a Linux guy.

Truth is, I was always a Microsoft guy, and that simply included Windows along with all of their development products. I used to be a hardware/network technician. I’d setup and maintain networks for medium to small businesses. Windows was always the way to go here, it’s what the users were accustomed to and expected. I’d usually setup a Windows NT server and from a dozen to maybe 30 client computers running various version of Windows including NT workstation. So Windows was just something I was always familiar with.

Even back then, I had the occasional urge to try other things. One of my first experiences with Linux involved using it as a firewall for a windows network on some cheap throwaway hardware that wasn’t good for much else. But it always seemed a pain to use, and I didn’t really understand it, despite having it working quite well for what I intended. I just didn’t see the point of not having a nice GUI and using cryptic commands to do everything.

Later, I learned to program in VBScript and VB using ASP and SQL. I became a web developer and abandoned the hardware gig. Software was so much more interesting. ASP became ASP.net, and VB became C# when I realized how crappy a language VB actually was. What made me want to change was my discovery of the original Wiki. I found a place where real programmers hung out and discussed anything and everything. I realized the world was bigger than VB. VB.Net fixed many of the issues with VB and is pretty much equivalent to C# in all but one area… culture.

What I really was abandoning was the VB culture. I’d outgrown it, I wanted to be involved in a culture that cared more about programming well. The VB culture is dominated by amateur programmers that are just happy to get something working, they tend to care very little about things like architecture, or patterns, or the aesthetics of good code. They don’t think of themselves as amateurs, many of them consider themselves experts, but start talking about object oriented programming or functional programming and the confused looks on their faces tells you they’ve not really looked into such things very deeply. Many think simply using classes makes code object oriented.

I was still firmly in the Microsoft camp at this point, though my change to C# had opened my eyes to Java, and more importantly object oriented programming. It was the Wiki that introduced me to Smalltalk. I just couldn’t help but notice how much Smalltalk was referenced whenever object oriented programming was discussed, nor how many famous authors credentials included a Smalltalk background. I decided I had to check out this Smalltalk thing. Now, at the same time, I was checking out the Lisp thing as well, but that’s not relevant to this story.

So I’m a web developer, my seeking tends to be guided by the need to make my job easier, to find better ways to automate myself. Obviously, I discovered Seaside. Seaside got me into a non Microsoft language. Around the same time, a buddy of mine who I’d met on the Wiki suggested cygwin. I’d been talking about wanting to learn a little more about Linux and he said I could do so without leaving Windows by using a better shell. Cygwin was the beginning of the end for Windows.

I started finding reasons to grep, cat, sed, sort, uniq. This was pretty cool, I was still in Windows but had a Linux command line and the shell became a bigger part of my toolbox. Now I find myself using a non Microsoft programming language, and having discovered PostgreSQL, a non Microsoft database. And now bash for my shell. Hmm…

So now I’m still hosting my apps on Windows servers, but I keep having problems crop up. I recently did a write up on Scaling Seaside which included a bash script for making sure the Seaside services were always up and running. Problem is, turns out the only thing making my Seaside services seem to die, was the bash script itself. Somehow lynx gums up Windows after a certain period of time and Windows starts having random network errors. I’ve taken the script down and now have another one running that uses wget and simply notifies me should any site I’m monitoring go down, or come back up.

So I find myself using all open source non Microsoft tools for everything except for the server’s operating system. Having become quite comfortable on the command line, it finally hit me, stop screwing with all these problems on Windows and try Linux again. Setting up new Seaside services on Windows is a multi step pain in the but. I’d thought I’d give a Linux a try and see how far it’s come since the last time I tried it. Boy was I surprised. In the next post I’ll detail my experience setting up a Linux server for hosting Seaside.

Rails vs Seaside

Sometimes a small sample is really helpful in showing the differences between two approaches. Ruby on Rails is a slick web framework for building web applications the old way. When I say the old way, I mean building URLs manually and passing parameters through query strings manually, i.e. marshaling session data manually.

Rails automatically maps URLs to controllers and methods in those controllers to setup the appropriate models, and automatically binds the correct view for that method, based on naming conventions of the files. It’s a great method and saves much of the hassle of writing a web app while enforcing a nice model view controller paradigm. Here’s a sample any Rails programmer will probably recognize, first list.rhtml…

<% @recipes.each do |recipe| %>
  <tr>
   <td><%= link_to recipe.title, :action => “edit”, :id => recipe.id %></td>
   <td><%= recipe.category.name %></td>
   <td><%= recipe.date %></td>
  </tr>
<% end %>
<p><%= link_to "Create new recipe", :action => “new” %></p>

and its controller…

class RecipieController < ApplicationController
    def list
        @recipies = Recipie.find(:all)
    end

    def edit
        @recipie = Recipie.find(@params[:id])
    end
end

Nice and clean, but the programmer is still working in a template language, requiring constant context switching between Ruby and HTML, and still manually building anchor tag URLs by calling a method and passing in the recipe’s id. Passing around ids requires that the next view, bound to the edit method in the controller, needs to look up the object from the database with that id from reading the request parameters. You can see this in the edit method of the controller, it sets up data in an instance variable in the controller so the view will have access to it.

This is classic web development done very cleanly, and honestly very Smalltalk’ish, however, passing around an object id isn’t very object oriented (it’s rather relational actually), and context switching between two languages while working in the view isn’t very fun. Instead of passing around an objects id why not pass around the object instead?

Enter Seaside, same code, different approach, more object oriented…

renderListOn: html
    self recipes do: [:recipe |
        self renderRecipe: recipe on: html ].

    html paragraph:
        [html anchor
            callback:[self editRecipe: Recipe new];
            with: ‘Create new Recipe’]

renderRecipe: aRecipe on: html
    html tableRow id: #recipie, aRecipe id; with:
            [html tableData:
                [html anchor
                    callback:[self editRecipe: aRecipe];
                    with: aRecipe title];
                tableData: aRecipe category name;
                tableData: aRecipe date ]

and the controller code…

recipies
    ^recipes ifNil:[recipes := Recipe findAll]

editRecipe: aRecipe
    self call: (RecipeEditor for: aRecipe)

Seaside puts the view and controller together in one class, the component, and it can do so cleanly because there is no templating language, rendering views are simply method calls in pure Smalltalk. So instead of having a controller, with a bunch of RHTML files and partials, we have components (aka view/controllers), with rendering methods (aka partial views).

It’s important to note however, that view code and controller code are still normally kept quite separate and organized using Smalltalk’s method categories. View methods are normally categorized as “rendering”, or something more specific like “rendering ajax”, while controller code is categorized in categories like “actions”, “queries”, “accessing”, or whatever categories you make up to keep your code organized. This is one of those Smalltalk things that no other language really has, and only exists in its environment so it doesn’t translate to sample code.

Now, the main thing to note here, is that objects are passed between views as actual objects using a constructor on the view (RecipeEditor for: recipe). One component simply creates and calls another. The components are also rendered in pure Smalltalk, which means they can be factored into smaller more reusable methods (aka partials), using all of Smalltalk’s existing tools, i.e. the refactoring browser. This is amazingly productive.

The anchor tag has a closure attached to it via its #callback: method, containing the actual code we want to execute when the user clicks the link. This closure, or block as Smalltalkers call them, gets turned into a URL automatically by Seaside and stored as a continuation on the current session. This means that RecipieEditor view doesn’t need to go back to the database and look up the recipe by its id, because it was given the actual recipe object directly (less load on the database). In essence, instead of passing a bunch of state through a URL manually, you simply say when this link is pressed, execute this code. This is a technique discussed by Paul Graham in his essay Beating the Averages that he used in ViaWeb. This one change drastically changes the way one thinks about, and builds, web applications and makes programming much simpler.

Notice how I’ve factored out the rendering of a single row into its own method. This sets me up to do some nice simple Ajax updates of individual row by being able to pass an Ajax rendering canvas through that same #renderRecipeOn: method. For example, I could re-render just that row, via Ajax, when a hyper link is clicked with just this…

html anchor
    onClick: (html updater id: #recipe, self randomRecipe id;
                    callback:[:ajax | self renderRecipe: self randomRecipe on: ajax]);
    with: ‘Replace random recipe with another random recipe’

So when I write a page, I break it up into rendering methods based on which parts of the screen I want to update via Ajax. This is similar to what Rails does with partials, except Seaside does it with ordinary objects and methods. Top to bottom, objects and method calls in pure Smalltalk, no web stuff.

This is what Seaside gives you, complete abstraction of the http request response cycle so you can program normally, as you would any desktop application, without all the extra hassles that web development introduced. Even abstracting away JavaScript for the most part. This translates into much faster application development, yes, even faster than Rails. It also means if you have to port a desktop application to the web, Seaside may allow you to do so without having to completely rework the existing design.

The price you pay… sessions and a little memory on the server. Yes it’s harder to scale than a session-less approach like Rails, but it will scale, and memory is cheap these days, far cheaper than programmers. Seaside, like Rails, is a very opinionated framework. Seaside’s opinion is that programming is the most expensive part of application development, so let’s optimize development time instead of CPU memory and cycles and throw out the (stateless/templated html) model of web development in favor of simpler web development in one language, where you have all of your tools available and aren’t constantly context switching between several languages.

Making a Connection Pool for Glorp in Seaside

First let me say…. Glorp rocks! Kudos to Alan Knight for this framework. I’m really liking it, having written two home brew O/R frameworks in the past (mostly to learn how, and in less capable languages than Smalltalk), I can appreciate the flexibility of its design. This is going on my list of programs to read thoroughly from time to time. It’s a very well written and very nice example of a well written OO system that anyone could learn a lot from. I’d add both Seaside and Magritte to that list as well. Reading great code is a lost art too few programmers do these days.

Glorp really gives me that object oriented feel and allows me to at least pretend I’m working with an object database, while keeping all the benefits of a relational database like constraints, indexing, and random queries. It’s far more capable than I thought it’d be and totally pluggable if you need to add any capabilities. It’ll do things Rails couldn’t dream of as far as mapping and querying goes, and it does it in native Smalltalk syntax.

OK, enough of the Glorp envy. I’ve been working to get Glorp, Seaside, and Magritte all tied together so I can have a full stack framework to work with that allows me to work in Smalltalk at every level. I’ve used many languages and nothing comes close to the productivity I feel in Smalltalk, so naturally, I’m looking forward to finally using it from top to bottom, html, biz objects, and sql queries, all in Smalltalk.

While working on an implementation of a sort of ActiveRecord, but using Magritte for the meta data instead of the database, I quickly found I needed to mary one Glorp session to one Seaside session to keep everything simple and intuitive. It’s a good match, however, I don’t want to keep a connection to PostgreSQL, they’re too valuable a resource to keep sitting idle and unused for 10 minutes while a session times out.

I played around a bit and found, at least so far, that within Glorp, the Squeak and Postgres adapters don’t really maintain any state and can be swapped in and out of an existing GlorpSession. I decided that I’d write a connection pool for Glorp’s SqueakDatabaseAccessor allowing me to tie a PostgreSQL connection to a request allowing much more scalability in the web scenario without risking running out of connections during peak loads. So, after a bit of playing around, I came up with a class called MGConnectionPool. I’m using the class side for all this code, taking advantage of the simple fact that in Smalltalk a class “is” a singleton ensuring there’s only one instance of the pool in the image.

MGConnectionPool class>>initialize
    lock := Monitor new.
    connections := Dictionary new.

MGConnectionPool class>>poolTimeout
    ^30 seconds

MGConnectionPool class>>withUser: aUser password: aPassword
    server: aServer database: aDatabase in: aBlock

    | connection result expired |
    "Grab a connection from the pool util you find one that
    isn't expired, logout the expired ones"
    expired := true.
    [expired]
        whileTrue: [connection := self
                        getConnectionUser: aUser
                        password: aPassword
                        server: aServer
                        database: aDatabase.
            expired := DateAndTime now - connection value > self poolTimeout.
            expired ifTrue: [connection key logout]].

    “pass the connection through the block, which will be the page
    request, and ensure it’s returned to the pool when done”
    [result := aBlock value: connection key]
        ensure: [self
                returnConnection: connection
                forKey: (self
                        makeKeyUser: aUser
                        password: aPassword
                        server: aServer
                        database: aDatabase)].
    ^result

MGConnectionPool class>>getConnectionUser: aUser password: aPassword
    server: aServer database: aDatabase 

    | key matchingConnections |
    ^ lock
        critical: [key := self
                        makeKeyUser: aUser
                        password: aPassword
                        server: aServer
                        database: aDatabase.
            matchingConnections := connections
                        at: key
                        ifAbsentPut: [OrderedCollection new].
            matchingConnections
                ifEmpty: [matchingConnections add: (self
                            newLoginForUser: aUser
                            password: aPassword
                            server: aServer
                            database: aDatabase)
                            -> DateAndTime now].
            matchingConnections removeFirst]

MGConnectionPool class>>makeKeyUser: aUser password: aPassword
    server: aServer database: aDatabase 

    ^aUser , ‘~’ , aPassword , ‘~’ , aServer , ‘~’ , aDatabase

MGConnectionPool class>>newLoginForUser: aUser password: aPassword
    server: aServer database: aDatabase 

    ^ (SqueakDatabaseAccessor forLogin:
        (Login new database: PostgreSQLPlatform new;
             username: aUser;
             password: aPassword;
             connectString: aServer , ‘_’ , aDatabase))
         login;
         yourself

MGConnectionPool class>>returnConnection: aConnection forKey: aKey
    lock
        critical: [aConnection value: DateAndTime now.
            (connections at: aKey)
                add: aConnection]

This allows me to create a subclass of a Seaside session and glue Glorp and Seaside together like this.

MGGlorpSession>>commit: aBlock
	^database inUnitOfWorkDo: aBlock

MGGlorpSession>>execute: aQuery
	^database execute: aQuery

MGGlorpSession>>register: anObject
	^database register: anObject

MGGlorpSession>>ensureGlorpSessionOn: aDbAccessor
	database
		ifNil: [database := GlorpSession new
						 system: (SBGlorpDescriptions
                            forPlatform: aDbAccessor
                                currentLogin database);
						 accessor: aDbAccessor;
						 yourself]

MGGlorpSession>>responseForRequest: aRequest
	^ MGConnectionPool
		withUser: (self application preferenceAt: #glorpUserName)
		password: (self application preferenceAt: #glorpPassword)
		server: (self application preferenceAt: #glorpServer)
		database: (self application preferenceAt: #glorpDatabase)
		in: [:dbAccessor |
			self ensureGlorpSessionOn: dbAccessor.
			database accessor: dbAccessor.
			super responseForRequest: aRequest]

Reading in the authentication from the current application config. Now I can feel safe using Glorp from Seaside, and from within any Seaside component, run Glorp queries with ease in a scalable manner. The code is totally generic and can reused for every future application by simply subclassing. Programming is getting more fun by the day; it’s going to be a good year for Seaside. All the necessary frameworks exist to build a truly awesome and “fully” object oriented web stack that doesn’t drag you down into the request response cycle inherent to other frameworks, even Rails. Glorp + PostgreSQL + Seaside + Magritte + Scriptaculous + Albatross + a little glue == Slick totally object oriented full stack Ajax web framework of the future, today!

Mapping Seaside Blog to PostgreSQL with Glorp

In a previous post I created a simple blog containing two business objects, BlogPost and BlogComment. I implemented persistence for that blog in the simplest manner possible, I put an OrderedCollection of BlogPosts in an accessor called repository on the BlogPost class…

BlogPost class>>repository
    ^repository ifNil: [repository := OrderedCollection new]

Allowing the class itself to serve as the database for all its instances. This is great for development speed, and gives you the ability to play and try out many different things until your object model settles down and you figure out what your model is really going to look like. Using the image as an object database allows you to remain nimble as you learn more about the problem and change your mind as you gain new insight into the domain model. Put off transactional persistence as long as you can, it’s likely you can build almost your entire program without actually leaving the image or thinking about a database.

Let’s assume the we’re at that point now, and we’re going to map BlogPost and BlogComment into a real relational database as if this were a production app. I’m going to use PostgreSQL and Glorp, my first time using either, and see what it takes. I’m not claiming anything I do here is best practice, only sharing my experiences as I learn.

For the record, Alan Knight, the author of Glorp, has a working implementation of ActiveRecord, somewhat like Ruby on Rails, that would allow me to avoid all this meta-data, but as far as I know, it hasn’t been ported to Squeak yet, and is still in Alpha; I hope he’s done soon.

Until ActiveRecord is available, I’ll have to write the meta-data the old fashioned way. After reading the Glorp Tutorial, I see I need to subclass DescriptorSystem and create a class containing all the meta data for classes, tables, and the mappings between them. I call it SBGlorpDescriptions.

It seems I need to override two methods to tell Glorp about the tables and classes…

allTableNames
    ^#(POST COMMENT)

constructAllClasses
    ^(super constructAllClasses)
        add: BlogPost;
        add: BlogComment;
        yourself

Then I need to write methods for the table meta-data. Glorp will create the actual schema in PostgreSQL for me from this metadata, as well as use it to map between tables and classes.

tableForPOST: aTable
    (aTable createFieldNamed: #postId type: platform sequence) bePrimaryKey.
    aTable
        createFieldNamed: #title type: (platform varchar: 100);
        createFieldNamed: #body type: (platform text)

tableForCOMMENT: aTable
    | postId |
    (aTable createFieldNamed: #commentId type: platform sequence) bePrimaryKey.
    postId := aTable createFieldNamed: #postId type: platform int4.
    aTable
        createFieldNamed: #name type: (platform varchar: 100);
        createFieldNamed: #comment type: platform text;
        addForeignKeyFrom: postId
            to: ((self tableNamed: #POST) fieldNamed: 'postId')

I also need to write methods for the class model which gives me a chance to control how Glorp loads the classes. For example, I may want to force Glorp to use accessors rather than direct instance variable access. Here I simply tell Glorp that a Post has a collection of Comments.

classModelForPost: aModel
    aModel
        newAttributeNamed: #persistentId;
        newAttributeNamed: #title;
        newAttributeNamed: #body;
        newAttributeNamed: #comments collectionOf: BlogComment

classModelForComment: aModel
    aModel
        newAttributeNamed: #persistentId;
        newAttributeNamed: #name;
        newAttributeNamed: #comment

Now Glorp has a meta-data model for both classes and tables. Now, given the table meta-data and the class meta-data, I create a map between them for each class on each class…

BlogPost class>>glorpSetupDescriptor: aDescriptor forSystem: aDescriptorSystem
    | table |
    table := aDescriptorSystem tableNamed: #POST.
    aDescriptor table: table.
    (aDescriptor newMapping: DirectMapping) from: #persistentId
        to: (table fieldNamed: #postId).
    (aDescriptor newMapping: DirectMapping) from: #title
        to: (table fieldNamed: #title).
    (aDescriptor newMapping: DirectMapping) from: #body
        to: (table fieldNamed: #body).
    (aDescriptor newMapping: OneToManyMapping)
        attributeName: #comments;
        referenceClass: BlogComment;
        collectionType: OrderedCollection

BlogComment class>>glorpSetupDescriptor: aDescriptor forSystem: aDescriptorSystem
    | table |
    table := aDescriptorSystem tableNamed: #COMMENT.
    aDescriptor
        table: table;
        addMapping: (DirectMapping from: #persistentId to: (table fieldNamed: #commentId));
        addMapping: (DirectMapping from: #name to: (table fieldNamed: #name));
        addMapping: (DirectMapping from: #comment to: (table fieldNamed: #comment))

I’m not using the real power of Glorp here, because my models mostly match, however, were I programming against an existing legacy schema, I might start to appreciate all this meta-data a bit more, knowing I could map any shape class to any shape table. This is where Glorp truly shines over Rail’s ActiveRecord, which is an extremely simple and not so flexible object mapping system. Everything I’m doing here, Rails could do easily, but Glorp is much more powerful and can be used against legacy schemas that look nothing like the class model.

Rails does one thing, one way, very well, with inferred meta-data and virtually no configuration. Glorp can do anything, any way you like it, but requires explicit meta-data, with a bit of configuration. Alan’s about to give us the best of both worlds, by inferring the basic meta-data like Rails does, but allowing you to mix and match it with custom meta-data for more complex mappings, I can’t wait, and I’m glad Rails has pushed Alan in this direction. Glorp will be much easier to use for greenfield applications if it infers the meta-data with reasonable defaults, and Rails has proven how popular this approach is with developers.

OK, now that all the meta-data and mappings are created, I need to have Glorp create the schema for me. I fire up a Workspace and create a Glorp session using my new SBGlorpDescriptions class…

login := (Login new)
    database: PostgreSQLPlatform new;
    username: 'xxxxxx';
    password: 'xxxxxx';
    connectString: '127.0.0.1_seasideBlog'.

accessor := DatabaseAccessor forLogin: login.
accessor login.
session := GlorpSession new.
session system: (SBGlorpDescriptions forPlatform: login database).
session accessor: accessor.

Then I tell Glorp to create my schema…

session inTransactionDo:
    [session system allTables
        do: [:each | accessor createTable: each ifError: [:error | error inspect]]].

So far so good, everything works, time to change the blog and query through Glorp. On my Seaside session, I created a few delegation methods to pass through to the Glorp session which it contains…

database
	^database ifNil: [database := self buildDbSession]

buildDbSession
	| login accessor |
	login := (Login new)
				database: PostgreSQLPlatform new;
				username: ‘xxx’;
				password: ‘xxx’;
				connectString: ‘localhost_seasideBlog’.
	accessor := DatabaseAccessor forLogin: login.
	accessor login.
	^(GlorpSession new)
		system: (SBGlorpDescriptions forPlatform: login database);
		accessor: accessor;
		yourself

unregistered
    super unregistered.
    self database accessor logout

commit: aBlock
    ^self database inUnitOfWorkDo: aBlock

execute: aQuery
    ^self database execute: aQuery 

register: anObject
    ^self database register: anObject

And then make a few changes to the main blog component…

blogPosts
    ^BlogPost repository reversed

Becomes…

blogPosts
    ^self session execute:
        ((SimpleQuery returningManyOf: BlogPost limit: 10)
            orderBy: [:each | each persistentId descending];
            yourself)

And I modify #newPost and #addCommentTo: to look like so…

newPost
    | post |
    post := self call: ((BlogPost new asComponent)
                        addValidatedForm;
                        yourself).
    post ifNotNil: [self session commit: [self session register: post]]

addCommentTo: aPost
    | comment |
    comment := self call: ((BlogComment new asComponent)
                        addValidatedForm;
                        yourself).
    comment ifNotNil:
            [self session commit:
                    [self session register: aPost.
                    aPost addComment: comment]]

And that’s it, the sample blog now works against PostgreSQL. In all honesty, it was a bit of work, more than I expected, but given Glorp’s capabilities, I understand the need for so much meta-data. I’ll sure be glad when Alan finishes his ActiveRecord implementation because most of the time, that’s all I need.

In the mean time, I’ll have to write up a quick code generator to generate most of this meta-data for me directly from the classes using reflection. I’ve got a bigger project coming up where I plan to use Glorp, and there’s no way I’m writing all this by hand again.

« Previous PageNext Page »