Archive for March, 2006

My favourite Ruby feature

Friday, March 31st, 2006

It’s not a Rails thing. It’s not even a Ruby thing.

I was just writing a bit of code and trying to force it to pass its test and I realised I was going about it all the wrong way. What I needed to do was something that I used to do all the time in Smalltalk and had forgotten about.

It was this:

column_names = MyClass.content_columns.collect do | column | column.nameend

or

columnNames:= MyClass contentColumns collect: [ | column | column name.].

if you prefer.

It doesn’t look like much but the Smalltalk style iterators and collectors for collections make dealing with arrays and lists and the like so much simpler. Consider the equivalents (if Delphi or Java had an equivalent to ActiveRecord):

List columnNames = new LinkedList();Iterator i = MyClass.getContentColumns().iterator();while (i.hasNext()) { Column column = (Column)i.next(); columnNames.add(column.getName());}

or even worse

var I: Integer; S: TStringList; C: TColumn;begin S:= TStringList.Create; try   for I:= 0 to MyClass.ContentColumns.Count - 1 do   begin        C:= MyClass.ContentColumns[I] as TColumn;     S.Add(C.Name);   end;   // do something with the list of names finally   S.Free; end;end;

OK, the Java doesn’t look too bad (and I’ve not used Java 1.5 so I don’t know about generics), but it reads, to me at least, like “go through the columns and do something with them” whereas the Ruby (Smalltalk) reads like “collect the column names“. And easier to read means easier to understand means easier to maintain.

ISAPI Ruby

Wednesday, March 29th, 2006

How about an ISAPI filter that intercepts all requests to a given IIS site?

  • On startup kick-start n WEBrick/Mongrel processes running on ports x to x + n.
  • It examines the URL to see if it has a ‘.’ in it.
  • If yes
    • Pass it to IIS to deal with (so that ASP.NET pages and static files are dealt with)
  • If no
    • Use a simple load-balancing algorithm (round-robin will do to start with although it would be better to work like FastCGI and have the option of starting new processes when demand is high)
    • Proxy the request in its entirety to the selected WEBrick/Mongrel instance
    • Return the response in its entirety to the client
  • On shutdown, gracefully bring down the N WEBrick/Mongrel processes.

This should mean that there is no Rewriter to set up and no FastCGI.

Installation should consist of installing Ruby, Rails, (maybe Mongrel), your application and the ISAPI filter (all of which ought to be easy).

The ISAPI filter ought to be relatively easy to write – all it does it control the WEBrick/Mongrel processes and proxy requests to them.

It would be even easier using an ISAPI application – however, that would require the rewriter (as the URL would change from /mycontroller/myaction/myid to /RubyISAPI.DLL/mycontroller/myaction/myid for the ISAPI to be invoked. However, that’s the easy bit of the install – it’s FastCGI that causes the grief, so it may well be worth looking at.

Rails 1.1

Tuesday, March 28th, 2006

Rails 1.1 has been released. Looks like I need to install Ruby 1.84 immediately!

Updates part deux

Saturday, March 25th, 2006

Chad Redman is having difficulties getting the code in the vendor folder to override the gem installation. I’ve never really tried it where the gem and the vendor folder are loaded together, always one or the other, so I’m not sure what is going on there.

Matthew Stephure asked about avoiding restarting IIS – when I was playing around I would just kill the RubyW processes with Task Manager. However, Matt says that this is causing him ‘ADO Invalid Class String’ errors. I’ve never seen these before but it sounds like a full IIS restart is definitely safer than killing individual processes.

Matt (and Chad) did however test Chris Lang’s hack to the allow query strings through the rewriter – apparently it works, although, as Chad noted, an arbitrary extra parameter is needed – Matt used a before_filter in application.rb to insert one.

Another problem – Matt noticed that when making an AJAX call the HTTP status appears to come back as 200 no matter what. Which isn’t good.

Lastly, Jens was asking about Windows authentication. After asking me the question he then discovered the following link: http://wiki.rubyonrails.com/rails/pages/WindowsDomainAuthentication – no effort on my part and a solution has been found.

On a more personal note, I have two more things to think about:

Firstly, after looking at updating the “all-singing all-dancing WEBrick installer” so it can become the “all-singing all-dancing IIS/FastCGI installer” and getting nowhere, I’m now thinking that writing an ISAPI equivalent to mod_ruby may be a better bet (LGPL‘ed of course). I’ve never written an ISAPI before but if I can incorporate FastCGI, Ionic Rewrite and all the other mucking about into a single DLL it’s bound to make my installation routine easier. If any of you have any experience of writing ISAPI DLLs I would be grateful of any pointers. My first stage, I guess, is to download the code to mod_ruby and see what that is doing (although I will probably write my DLL in Delphi rather than your steenkin’ C).

Secondly, it’s fast becoming apparent that there are a lot of people interested in running Rails on IIS and there isn’t that much information out there. I am currently doing this part-time, my day job is really Delphi and the Rails stuff came about because I found it interesting and we needed a web application throwing together very quickly. The issues noted above show that I don’t always have time help people out with their problems (sorry Erwin), although I am happy to be asked – however, I reckon between us, we can figure it all out. A blog isn’t really the best format for that though – so should I set up a forum to discuss the issues we come up against and any possible solutions? I’m happy to host it if you’re happy to post there. Let me know what you think.

The One-Paragraph Book Review

Monday, March 20th, 2006

Well, actually two book reviews, although each is only a paragraph.

Micro-ISV: from Vision to Reality by Bob Walsh (APress).

A book by one of the moderators on the Joel on Software forum about the ins and outs of setting up your own (micro) independent software vendor. Lots of information on tax, web forums, interviews with people who have done it or are doing it and lots and lots of plugs for Joel and FogBugz. And, to tell you the truth, not much fun to read. As Mr Walsh states, his style is just the facts but it just left me bored. I’m sure there’s useful information in there but I put the book down and didn’t pick it up again.

Update: I think I was being a bit unfair. It’s a reference book, not a reading book. Sorry Bob.

Getting Real by 37Signals (37Signals).

A book by the web’s hottest company about the process that they followed to write Basecamp, Backpack, Campfire et al. Obviously, if you’re reading this site you already know something of 37Signals as Rails is the brainchild of David Heinemeier Hanson and was created to write Basecamp. And the book, like the products and the framework is fantastic. I read the first chapters and I was itching to go off and set up my own company. The passion and enthusiasm positively drips off the (electronic) page and the book is an inspiration. Even though it is literally the opposite of Micro-ISV – virtually no facts, just a 177 page pep talk, with the disclaimer that “this is what worked for us, it may not work for you“. If you ever feel a bit down about writing software, read it and it will bring you back to life.

Updates

Tuesday, March 14th, 2006

I’ve not had much time recently so a very brief update based upon the comments on my “setting up IIS for Rails” article.

Chris Lang (www.pod2mob.com) has sent through a new set of rewrite rules and associated changes to request.rb that, in theory, allow query strings to be passed through IIS to Rails (and hopefully mean that the web services stuff should work). I’ve not tried them yet but they look like they should do the trick.

Erwin Quita has been having difficulty setting up IIS (getting a “specified module could not be found” error. It appears that the difference between our setups is that I am on Ruby 1.8.2, not 1.8.4. I’ve not had the time to try an updated installation so I don’t know what is going on there (but see below for more on this).

However, I am about 60% of the way through persuading my bosses to let me write a whole new application in Rails (none of this legacy nonsense). As we are very much a “Microsoft shop”, even if I am allowed to write the Rails application, it will probably have to be deployed on Sql Server with IIS. Once I get the go-ahead that gives me full licence to spend a lot of time investigating the quirks of a full-on live installation with (hopefully) many, many clients attached. The only question is will this new application make money – if the market research suggests it will (which is my, and our sales guy’s, gut feeling) then be prepared for an onslaught of updates as I discover new and ugly quirks to getting Rails working on the Microsoft platform.

And one last thing; it took my Powerbook two years of being lugged and banged about every day before the DVD drive died. It’s taken this Dell about six weeks.

Thank you to everyone who takes the time to read this and even more to those who have commented. I do appreciate the interest and hope you all get some use out of this blog.

SQL Server Stored Procedures and Rails (again)

Thursday, March 9th, 2006

I have updated the SQL Server Stored Procedure module with a bug-fix.

The all-singing, all-dancing, all-in-one WEBrick web application installer!

Friday, March 3rd, 2006

The “all-singing, all-dancing, all-in-one WEBrick Web Application Installer“, version 0.1 is now available for you to play with (under the terms of the LGPL). You can read the instructions here but I’ve provided a quick summary, below. In order to use this you must download the excellent (and free) InnoSetup.

The major grief with installation is when things go well they go well. When things go wrong it’s because something unexpected happened! This installer has worked absolutely fine on every machine I’ve used it on. However, my instructions for setting up IIS have also worked fine on every machine I’ve used it on. Just because it works for me doesn’t mean it will work for you. So please download the installer, use it, break it, fix it and let me know how you get on.

Overview

This InnoSetup file compiles a Ruby on Rails application and the Ruby 1.8.2-15 installer into a single Setup.EXE file. When run on a customer’s machine it will install Ruby, if required, install your Rails application, copy some database and email configuration parameters into your application and then create a Windows Service that will start your application on machine startup. It expects your application to use SQL Server although it wouldn’t be hard to change it to something else.

What does it do?
The installation will require administration rights as it sets up Windows Services.

Firstly, it checks to see if Ruby is installed – if not then it invokes the standard Ruby installer.

Next it asks for some configuration details:
Your Web Server configuration – the port number to use and when to clean up the session files (defaulting to 80 and at 4:00 every day respectively).
Your Database configuration – the database server, database name and username and password to use to log in.
Your Email configuration – the email server, port number and domain name to use.

Then it unpacks your application to the specified folder (by default C:\MyAppName) and writes the configuration parameters collected above to the relevant configuration files.

Lastly it, optionally, asks if you want to install the Windows Service (called MyAppName), to start it automatically and whether you want to schedule a task to clean up the session files.
instsrv and srvany (from the Windows Server Resource kit) are used to create the service.
net start is used to start the service.
at is used to create a scheduled task to clean up the session files.

Potential Future Enhancements
At present the installer is designed for SQL Server databases only. It generates an ADO specific set of database connection parameters. This should be amended to ask for an adapter and generate the parameters accordingly.

The installer could detect if any migrations are included and run them at the end of the installation process to ensure that the database is at the correct version. However, on new installations it will require that the database is created before the installer is run.

A separate version of this installer is planned that will install the web application into IIS using FastCGI.

Licences

Wednesday, March 1st, 2006

I’ve chosen to licence my SQL Server stored procedure module, plus any of the remaining stuff I publish on here, under the terms of the GNU Lesser General Public Licence.

“Why?” I hear you cry, “are you a communist?

The reasons are quite simple.

1) I need something that is commercially compatible as I intend to use this in my company’s commercial creations.
2) I want something that is free – by which I mean that you can take and use in your own products, whether commercial or not. I want you to be able to benefit from my thoughts.
3) I want something that you cannot steal. This is my code. If you alter it in some way to make it better then you cannot hide it away so that only you benefit from it. I want everyone to at least have the option of benefitting from this code.
4) I do not own you. Just because I wrote a bit of code you are using does not give me the right to impose my views on the rest of your code.

In my opinion, and I am not a lawyer so feel free to let me know if I am wrong, the LGPL is the only licence that fits the bill.

Traditional commercial licences do not fit because of 2).
The BSD/MPL-style licences do not fit because of 3).
The GPL does not fit because of 1) and 4).

So I think that proves I’m not a communist.

Patched

Wednesday, March 1st, 2006

The web-service bug where Rails fails to marshal bit fields looks to have been fixed. The diff can be downloaded from here.