Thursday, March 20, 2008

Running a schedule task for a rails application

There are several ways described in ruby on rails wiki. But for our need, I took the simplest one - create a cron entry that executes RunnerScript.

At first create a static Model method. RunnerScript can only access model and run its class methods, it cannot access controllers. For example, we needed a script that periodically check for expired items and mark. So, I wrote a class method like follows -

def self.mark_expired_items()
update_query = "status = #{Constant::Item::STATUS_EXPIRED}"
# find expired items
update_conditions = "status = #{Constant::Item::STATUS_PUBLISHED}
AND created_at < '#{(-Constant::Item::EXPRITY_TIME).days.from_now.to_s(:db)}'
"
update_all(update_query, update_conditions)
end



Then create a cron entry that runs this periodically. For our purpose (we wanted to expire item 4 days after publishing)
0 * * * * <project_path>/script/runner Item.mark_expired_items

Thats it. This script checks every hour for expired items and mark all of those as expired

Tuesday, March 18, 2008

ssh login without re-entering password

At my work, i have to enter our hosting server. Sometimes, several times a day. And obviously I have to enter password to get through.

I knew the solution before. We used to do this in our distributed systems lab at college. Because, sometimes it becomes necessary to enter a remote machine without password by the automated scripts.

And today I had to rediscover this again ;)

Enter the remote machine and check there exists .ssh folder under `~` (home) folder. if it doesn't exist, create one.
mkdir ~/.ssh

then 'exit' to come back to your own console.
2. create your own key. For simplicity, just press enter at all prompts
ssh-keygen -t dsa

3. Copy your ssh key to remote host
cat ~/.ssh/id_dsa.pub | ssh <remote_host_address> "cat - >> ~/.ssh/authorized_keys"

VoilĂ ! You're done. Now try to ssh again to the remote host. You'll get the remote shell without any password :)

Monday, March 17, 2008

Migrating subversion repository - forking new project

This far in our company we were using single repository project to maintain all our projects. That is, we create a new subdirectory in the root project directory when we need to start another project. It requires less server side maintenance at the cost of less security. It was just fine for a small developer team, until recently.

Now I need to create projects out from each directory under root (i.e. each project), with revision number starting from 1 for each project.

The steps I followed -
1. Created svk mirror of each projects root directory.
2. Dump svk's local mirror. This creates a plain svn dump maintaining projects revision number
3. Manually removing projects root directory
4. Load svn dump to a new svn repository

That's it :)

1. Create svk mirror for each project
a. initialize local mirror
svk mirror <svn url>/<project_directory> //<project_name>

b. sync, copy project directory to local svk mirror
svk sync //<project_name>
2. Dump local svk mirror
svnadmin dump ~/.svk/local > <dumpfile>
3. Manually removing project's root directory


4. Create a new project and load the dump

sudo svnadmin create <project_name>

sudo svnadmin load <project_name> < <dumpfile>

Monday, February 25, 2008

Rails Time and Database

Last few days I improved rails code related to time function in several places.

1.

Rails extended basic Time class to give output in several format. So that you can output in database datetime format by passing :db symbol as argument to Time's to_s() method. Previously I produced database format manually
Time.now.strftime("%Y-%m-%d %H:%M:%S").to_s
now, it simplifies to
Time.now.to_s(:db)
Detail documentation can be found here

2.
To parse database date to ruby Time, I used this.
Time.parse(token.created_at.to_s)
where created_at is DateTime type field in Token model

3.
To get back-and-forth between Unix Timestamp and ruby Time, you can simply use -
Time.now.to_i
and to read -
Time.at(unix_timestamp)