Friday, May 30, 2008

Spread Firefox 3: Countdown to Download Day

UPDATE:

Got a nice certificate from Mozilla.org for participating... yeeha...








I might've missed Pi Day this year, but 3.o will do...

Join in on Download Day for Firefox 3. Maybe we can set a new world record!





Download Day - JapaneseDownload Day - English

Wednesday, May 21, 2008

Google Web Toolkit on Google App Engine: Join in a performance test!

There's an interesting experiment using the Google Web Toolkit and Google App Engine posted here. I am very curious to see what sort of performance can be had when the GWT is paired with App Engine, with no explicit, special optimizations.

If you are free and want to join in the fun, just hit http://qwerty.codathlon.com on May 23, 2008, 16:00, Paris-time. That's 23:00 here in Sapporo, Japan.

I am so in.

Monday, May 19, 2008

Japan's IT state of the nation: bleak outlook

Good thread on slashdot regarding outsourcing to China.

Here in Sapporo, the local municipal government has a deal with IT companies based in Shenyang. Having personally been involved in project management capacity with a company in Shenyang recently, as well as having worked in the past with support and development teams based in mainland China, I am rather doubtful of the present Sapporo-Shenyang partnership. More so since there are no more direct flights between Sapporo and Shenyang.

I think that the odds are stacked against you in terms of meeting a project deadline on time and with high-quality, largely due to differences in cultural expectations and the lack of a good telecommunications infrastructure in Shenyang. But even more than that, afaik, there is a sorry lack of experience and understanding about such globalized, international endeavors here in Sapporo. It really is disconcerting to see the hit-or-miss approach being taken by some companies.

I suppose that this may have a lot to do with the dwindling numbers of university graduates with technology degrees. I do not think, however, that a strategy of retaining only project managers and outsourcing the bulk of work will succeed in the end, both for the enterprise and for the local and national economies.

Wednesday, May 14, 2008

RSpec and stubbing ssl_required

Here's a quick rspec stubbing tip for those of you using RSpec and Spec::Rails with a need to stub out the controller behavior for ssl_required. I wrote this tip with mocha in mind, but you can easily apply this to whatever mocking/stubbing framework you may be using.

First, let's take a look at the source for the SslRequirement module, paying attention to the the before_filter bit:


module SslRequirement
def self.included(controller)
controller.extend(ClassMethods)
controller.before_filter(:ensure_proper_protocol)
end

...

private
def ensure_proper_protocol
return true if ssl_allowed?

if ssl_required? && !request.ssl?
redirect_to "https://" + request.host + request.request_uri
flash.keep
return false
elsif request.ssl? && !ssl_required?
redirect_to "http://" + request.host + request.request_uri
flash.keep
return false
end
end
end

You can see that it is the private method ensure_proper_protocol that is being declared as a filter for the controller. Since a controller that declares ssl_required will automatically inherit the methods listed in SslRequirement, you can stub the SSL-checking behavior in mocha-style for your controller's behavior-driven rspec test like so:

controller.stub!(:ensure_proper_protocol).and_return(:true)

Just declare the above stubbing in a setup block, and you are good to go!

Uninitialized Constant CGI::Session::ActiveRecordStore NameError

If you've found this post by keyword search, let me ask you: Are you using the Rails ActiveRecordStore along with the Ruby-GetText-Package ruby gem? And are you seeing an ugly, mysterious error that looks something this when starting Rails or even executing script/console:


[me@myserver]# mongrel_rails start
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
/var/www/apps/argent/vendor/rails/actionpack/lib/../../activesupport/lib/active_support/dependencies.rb:478:in
`const_missing': uninitialized constant CGI::Session::ActiveRecordStore (NameError)
from /var/www/apps/argent/vendor/rails/actionpack/lib/action_controller/session_management.rb:24:in `const_get'
from /var/www/apps/argent/vendor/rails/actionpack/lib/action_controller/session_management.rb:24:in `session_store='
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:328:in `send'
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:328:in `initialize_framework_settings'
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:327:in `each'
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:327:in `initialize_framework_settings'
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:324:in `each'
from /var/www/apps/argent/config/../vendor/rails/railties/lib/initializer.rb:324:in `initialize_framework_settings'
... 15 levels...
from /usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.4/bin/../lib/mongrel/command.rb:212:in `run'
from /usr/local/lib/ruby/gems/1.8/gems/mongrel-1.1.4/bin/mongrel_rails:281
from /usr/local/bin/mongrel_rails:19:in `load'
from /usr/local/bin/mongrel_rails:19


At the time of this post, I only saw three hits when Googling on "ruby", "rails", and "uninitialized constant CGI::Session::ActiveRecordStore (NameError)". 2 links to Japanese blog posts, the 3rd to a Rails forum in Polish. None helped me resolve the above problem.

But I was Googling in English.

When I tried changing tactics and Googling in Japanese instead, I found this link, and a hint that led me to the following solution...

There is some kind of require collision happening when trying to use both the ActiveRecordStore for session management and the gettext package for localization/internationalization. The answer is to put the require 'gettext/rails' declaration well after the default Rails environment bootstrapping. In my environment.rb, I've got my requires declarations set up like so:


# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot') # default
...

Rails::Initializer.run do |config|
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with 'rake db:sessions:create')
config.action_controller.session_store = :active_record_store
...
end

# After the Rails::Initializer.run block, just before end of file
require 'jcode'
require 'gettext/rails'


In doing so, you can avoid any namespace collisions between the default Rails requires and that for gettext/rails. Hope this saves you some time and headaches.

Monday, May 12, 2008

cron jobs for PostgreSQL users without using passwords

Ever needed to run some kind of cron job on a PostgreSQL database, but was stumped for not being able to specify a database user's password with the psql utility?

In using PostgreSQL with Ruby on Rails, I often have to set up regular cron jobs to clear out stale data, such as session data when using ActiveRecord as the session storage mechanism. Instead of coding up some object to react on a timer, you can simply use cron to do your bidding. But your regular cron job to connect to the PostgreSQL database needs a user, and that user needs to provide a password when connecting. Here's how you can set this up by creating a new UNIX/PostgreSQL user and configuring this user's database access in pg_hba.conf.

First, create a new UNIX account for your user. We will use the same username when creating a database user account as well. Why? Well, PostgresSQL allows connections not only over TCP/IP, but also over UNIX domain sockets. And, you can configure pg_hba.conf so that when a certain database user attempts to connect over a UNIX domain socket, PostgreSQL will check for an existing UNIX user account. If this UNIX user is the same as the user account attempting the database connection, then PostgreSQL will treat such access as trusted, hence no explicit password passing will be required.

For example, let's say that I want to clear out stale session data from my Rails sessions table. I first create a UNIX account for my database user.


# useradd victor

Don'f forget to set up a good password to victor. You may also want to revoke permissions from groups and others to access this user's home directory. For production environments, you want to be sure to assign victor to a group with limited UNIX user privileges, since we don't want people to misuse victor and mess with our database.

Next, we create a PostgreSQL database user account for victor, using the same username. We will create this database user with limited privilege on the sessions table, for security's sake. Assuming that the we are talking about the default Rails sessions table, we have:

# psql -U [database admin] [your_database]
psql@your_database> create user victor with password 'somepassword';
psql@your_database> grant select, delete on sessions to victor;

There! Now we have a PostgreSQL database user corresponding to our newly created UNIX user account.

Next, we add this line to our $PGDATA/pg_hba.conf file:

# TYPE DATABASE USER CIDR-ADDRESS METHOD
local [your_database] victor ident sameuser


This is how we allow the new user to connect to the PostgreSQL database using a UNIX domain socket connection. Logging into your UNIX machine as victor, you can now set up a simple cron job like so:

$ crontab -e
# crontab for victor
# Let's run a simple psql command as victor to delete stale rows in sessions table
# Execution time is
0 0 * * * /full/path/to/psql -U victor -c "delete from sessions where \
updated_at < (now() - interval '6 hours')" [your_database] > /dev/null


So now we are good to go, with a UNIX/PostgreSQL user whose cron job will run daily at midnight, clearing out stale rows in the sessions table for our Rails ActiveRecord session management. And all without having to explicitly specify the password!