Techblog

Tech Blog

Contributions by Willem van Bergen

About Willem van Bergen

My website, online since 1999: www.vanbergen.org. I can also be found on Flickr, GitHub, LinkedIn and - of course - on Google.

24 December Rails and Merb merge!

Good luck to the merged Rails team and hopefully Rails 3 will kick ass! Let’s hope git will really deliver on this gig! Try to refrain from using git blame too much when resolving merge conflicts. ;-)

git checkout rails && git merge merb

4 Comments - Tags: , , , , , , ,

18 December Using your own site as OpenID identity

My personal domain vanbergen.org is almost 10 years old. Besides the accompanying e-mail address, I’ve never used it extensively, but its one of the oldest pieces of my “legacy” that can be found on the Internet and it is the starting point of my online identity.

Lately, major internet companies have embraced the OpenID standard to allow other sites to login with the login credentials of these major sites, basically running an OpenID server. (Curiously, they do not support consuming OpenIDs themselves, so I still have to trust them with my password. What’s up with that?) I can use most of the sites I have an account on as OpenID identity. For example, my Flickr page is an OpenID identity URL. With more and more sites supporting consuming OpenIDs (including Floorplanner!), I will not have to remember all those passwords and the internet will become a better place because of it.

It would be nice to use my 10 year old domain name as my OpenID identity. This is actually very easy because of delegation. I do not have to run my own OpenID server: I can just add a header to my site that points to the OpenID server that I will be using. I have chosen to use my Google Account as OpenID server. To accomplish this, I simply added the following tag to the <head>-section of the vanbergen.org site:

<link rel="openid2.provider" 
    href="https://www.google.com/accounts/o8/ud" />

Now, I can simply enter “vanbergen.org” when my OpenID identity URL is requested on a site. How neat is that? That site will check my personal site for this tag and will redirect me to the Google Account page, on which I can confirm that I want to login to that site. Note: the site has to support OpenID 2.0, because Google does not offer an OpenID 1.0 provider. Luckily, most sites do.

OpenID login on Floorplanner.com

I do not know what happens to the sites I have registered on with OpenID if I decide to change my OpenID provider and I change the value on vanbergen.org accordingly. Does anybody know if my existing OpenID accounts will keep working in this case?

1 Comment - Tags: , , ,

14 December Working with git branches

Because Jaap finally convinced Gert-Jan, we have moved to the Git version control system for the main Floorplanner repository. Now we can use branches for different functionality far more easily. As an easy reminder to some common Git tasks I will need regularly, I have written down some Git recipes. This is basically meant for me and my fellow developers, but maybe it can help you as well. Suggestions to improve my workflow are welcome!

Displaying the current branch in your prompt

Because I will be using branches more regularly now, it is nice to know what branch I am currently working in. git branch will provide this information, but it can be more direct by including the current branch in your terminal prompt.

To display the current git branch in my terminal prompt, I have added the following to my Bash configuration file ~/.profile:

parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \[\1\]/'
}
 
PS1='\[\033[01;37m\]\w\[\033[00;35m\]$(parse_git_branch)\[\033[00m\] \$ '

I use a black, semi-transparent terminal with white text, and pink branch names. Change the colors to your own liking!

Git - branch in terminal

Working on a remote branch that is not available locally yet

If you want to help out on a branch that somebody else started and has pushed it to the remote repository, you can checkout this branch and make it “track” the remote branch.

$ git checkout -b newbranch origin/newbranch

In this example, origin/newbranch is the branch in the remote repository. Locally, this branch will be called newbranch. A simple git pull will update my branch with the latest changes from the remote branch later on, git push will send my changes to the remote server.

Git - track remote branch

Creating a new branch and pushing it to the remote server

Sometimes I want to start a new branch myself if I want to work on a new feature or on disruptive refactoring of the main codebase.

$ git checkout -b feature

The feature branch is now available locally. After some time, I want to share my current changes in this branch with other developers. I should make the branch available in the remote repository so other can access it like I described above.

$ git commit -m "Added initial version of %feature%"
$ git push origin feature

Git - push local branch to remote

The feature branch will now be available to other developers as well. Note that the local feature-branch is not tracking the remote branch of the same name. This can be enabled by changing the configuration of the repository.

Merging a branch

After work is completed on my feature-branch and it is tested thoroughly, I want to merge the branch with the master branch of the project. To make sure the merge with the master branch is seamless and all possible merge conflicts are handled beforehand, we first run git rebase. This ensures that the changes in the feature branch are relative to the latest commit to the master branch and can therefore be applied by a “fast forward”. It is best to run git rebase from time time to time while you are developing in the feature branch to make sure your work does not divert to much from the main development in the master branch.

  # make sure that the current branch is seamlessly
  # mergeable with the master branch
$ git rebase master
  # switch to the master branch
$ git checkout master
  # now, merge the feature branch
$ git merge feature
  # publish the merge to the remote server
$ git push origin master

Git - merge branch

I can now delete the local and remote feature branch, as the changes have been incorporated in the master branch:

$ git branch -d feature
$ git branch -d -r origin/feature

2 Comments - Tags: , , , , , , ,

11 December Rails 2.2 support for request-log-analyzer

I just released version 0.2.0 of request-log-analyzer, our tool to analyze request log files that are generated by Rails and Merb for performance tweaking. This new version supports the new log format of Rails 2.2, which has changed slightly.

An updated gem should be available any minute now. Run sudo gem update to upgrade the newest version.

No Comments - Tags: , , , ,

26 November Generating thumbnails

I would like to thank you all for helping us build our thumbnail database!
I presume this statement might be in need of some clarification, so bear with me when I go into the technical details on this one.

For every design that is saved on Floorplanner, we create a thumbnail in JPEG format. We use these thumbnails for the gallery, and now we have included them on everyone’s dashboard. However, for various reasons, we do not have a thumbnail available for every design. However, with your help, we are improving the thumbnail database while you our browsing the site!

The thumbnail images are stored on Amazon AWS S3. We know the URL that a thumbnail of a design should have, but we do not know if it actually is available. In the latter case, the result is a nasty image not found placeholder on the dashboard. This of course is not acceptable! We cannot know if a thumbnail exists other than doing a request to the URL and see whether we get an image back from Amazon, or a HTTP 404 status. This is a very time-consuming procedure to run server side so we chose to find a client-side solution.

We found that javascript can be used to check if an image exist. An AJAX call cannot be used, because cross-site calls are not supported. However, the javascript Image object can be used for this purpose.

var img = new Image();
img.onload = function(event) {
  // image was found and loaded successfully
  document.getElementById('img-tag').src = img.src;
};
img.onerror = function(event) {
  // An error occured while loading the image
  document.getElementById('img-tag').src = '/images/thumb-unavailable.jpg';
}
 
// Setting the src property will trigger the events.
img.src = 'http://link.to.amazon.s3/design/thumbnail.jpg';

A nice thumbnail not available image will be shown if the thumbnail file cannot be found on S3. This is much nicer, and the check is completely done client-side! However, we found a way this could even be better by changing the onerror event handler. Instead of displaying a thumbnail not available image, we can simply load a small instance of the Floorplanner application to display a small version of the design. Moreover, we can instruct it to generate a thumbnail JPEG and save it to S3!

So, every time you see a small Floorplanner loading on your dashboard, you are creating a missing thumbnail. Next time, the thumbnail will be available on S3 and there will be no need to start the Floorplanner application. A nice example of distributed computing, mixed with a hint of SETI@home. I like it!

No Comments - Tags: , , , ,

21 September HTTP status exception handling plugin

Some time ago, I wrote about putting HTTP status code to use for your Rails application. For my reinvigorated project, I wanted to apply the same technique. Instead of re-implementing it once again, I created a Rails plugin called http_status_exceptions to easily add this functionality and I have put it on Github. For more information on how to install and use the plugin, see the project’s wiki.

No Comments - Tags: , , , , ,

20 September Batch file renaming

I just started working on an old Rails project after having neglected it for 15 months. Most of the view files still had the good old .rhtml extension. I was too lazy to rename these files by hand, both on my file system and in the git repository. I used the following Bash commands to do the job:

First, I renamed all the partials to the .erb extension. Note: I am not using .html.erb, as some of these partials are used in js-formatted responses as well:

for i in `find app/views/**/_*.rhtml`; do \
  git mv $i `echo $i | sed s/\\.rhtml$/.erb/`; \
done

The remaining files could now be renamed to .html.erb with a similar command:

for i in `find app/views/**/*.rhtml`; do \
  git mv $i `echo $i | sed s/\\.rhtml$/.html.erb/`; \
done

Note that this technique works with Subversion as well: just substitute git with svn in the command above. A regular rename is possible as well by leaving out git altogether!

Now my file names are Rails-compliant again, I can start refactoring all the code that is not up to current Rails standards anymore. Ah, the virtues of developing with a rapidly evolving framework…

1 Comment - Tags: , , , , ,

13 September Remote branches in git

I have been using git for a while now, and I believe I have the the basic workflow under control. Committing, reverting, using local branches for major refactoring work: been there, done that! ;) However, I recently got some collaborators on my github-projects, I had to start working with other remote repositories and branches.

I found this blog post, which was really helpful. I am sharing some others things that helped me in the last couple of weeks. Hopefully, this saves other people some time Googling. If you know a better ways to accomplish these tasks, please let me know!

Things to remember about remote branches

Because I had some troubles discovering how to properly work with remote repositories, I am sharing what I found. The most important things to remember:

  • Your local branches are not really connected to the remote branches. It is therefore possible to mix up branches, but this is usually not what you want :-)
  • Never forget to switch to the correct local branch (using git checkout local-branch.
  • The names of the local and remote do not need to match.
  • Before you can push changes from a local branch to a remote branch, all the commits of the remote branch have to be included in your local branch. This can be done using by executing git pull remote-name remote-branch in your local branch.

Checking out a newly created branch in a remote repository

Bart is implementing Merb log parsing for request-log-analyzer. He has put his progress in a separate branch of the github project. My local repository does not yet include this branch, but I want to check it out. Note that I am using a different name than the branch name on the github project.

$ git branch merb origin/generic_base
$ git checkout merb

When the new functionality is finished, the following commands will merge the changes in the merb branch to the master branch.

  # goto my local master branch and merge the merb-branch
$ git checkout master
$ git merge merb
 
  # push the changes to the master branch on github
$ git push origin master

Merging back a fork

Wes Hays is helping me out on the scoped_search plugin. He implemented OR in the query language in his own fork. I wanted to merge his changes back to master branch:

  # add a reference to the remote repository
$ git remote add gbdev git://github.com/gbdev/scoped_search.git
 
  # create a local branch for the fork to follow a remote branch
$ git branch gbdev-fork gbdev/master
$ git checkout gbdev-fork

Now, my local gbdev-fork branch contains Wes’s code. Because Wes’s repository was forked from my repository, git will know that most of the history of my master branch and gbdev-fork branch is the same.

After some testing, I was ready to include his changes by merging the gbdev-fork branch into my local master branch:

  # go back to my master branch, and merge the changes
$ git checkout master
$ git merge gbdev-fork
  # push the changes to the master branch at hithub
$ git push origin master

Pushing tags to a remote repository

You can create tags locally, but you probably want to send them to the remot repository as well:

  # create a local tag "tagname" with the given message.
$ git tag -a "tagname" -m "message" 
  # send your tags to the remote repository "origin"
$ git push origin --tags

4 Comments - Tags: , , ,

29 August Rails-log-analyzer matures

Since I announced rails-log-analyzer some weeks ago, quite a lot has happened! Apparently there is some interest in such a tool: on this blog we get a lot of traffic looking for more info, the github project already has 22 watchers and it even has been forked!

In the mean time, Bart and I worked hard to add new functionality and refactored the internal design. As a result, I have released request-log-analyzer 0.1.0 today!

Changes: 

  • The project is renamed to request-log-analyzer, because we plan to support log files from other frameworks as well; Merb is planned to be supported in the near future.
  • The tool is distributed as a gem, making it much easier to install and update.
  • More reports, colorized output, parsing progress bars, command line arguments, etc…
  • Added a tool to create a SQLite database with all the parsed info from the log file, so you can do your own analysis.

Installation:

gem sources -a http://gems.github.com
sudo gem install wvanbergen-request-log-analyzer

Usage:

request-log-analyzer  [LOG FILES*]
request-log-analyzer -c 20 -z log/production.log

Please let me know what you think! If you have any problems using the tool, do not hesitate to contact me!

13 Comments - Tags: , , , ,

15 August Rails log analyzer

My friend Bart from movesonrails.com just blogged about Rails log analyzer, a command line tool to get performance statistics for your Rails application by parsing its log file.

What started as an exercise for me to write a command line ruby program, has been extended and improved by Bart to be actually useful! We decided to release it under an MIT license. You can found the source on github. The project’s wiki contains usage information and an example of the output it will produce.

5 Comments - Tags: , , ,