Archive for July, 2009

Integrating timezoned legacy dates into UTC based Rails application

July 23rd, 2009

Ruby on Rails (RoR) has become one of industry’s fastest and the easiest web application framework to adapt to compared to some of the more mature ones such as J2EE, ASP.NET, etc.  So much so that other languages such as Perl and Python quickly starting spurring up their own web application frameworks that were modeled off of how Rails implemented the MVC pattern in such a pragmatic and simple manner.

As I was messing around with my first RoR project at work, we ran into an issue with incorrect rendering of Date/Time data retrieved from our legacy database.  After some research online, I realized that some incorrect decisions in our legacy data storage had finally crept up when the right approach was applied on the front-end.

The problem was that Rails stores all date values in UTC format in the data store and then displays a localized version based on the user’s locale in the front-end.  Unfortunately, the dates in our legacy data store were already being stored in Pacific time zone and so when rendering the date in the Rails based front-end application, an offset was being applied to the already offset date value resulting in an incorrect value.

Take a look at Rails 2.1 Time Zone Support: An Overview for a good overview on Rails time zone support.

So…Now what?

Well, I knew that we were constraint by the legacy data and because other legacy apps were already relying on the data stored as is, we cannot fix the problem on the data side by updating all date/time values using SQL.   Plus, these incorrect date/time values were spread out throughout the database in various tables making it very difficult and fairly easy to miss some value in some table.  We also needed to keep this date/time storage decision intact when updating data from our Rails app which means somehow we’d have to make Rails not store the date/time values for those specific dates in UTC again for any legacy apps consuming the same data.

But how do we do this by not mucking with Rails internals especially since this UTC conversion took place at the DB adapter levels?  The answer is a Rails plugin.

Rails Plugin

More on this soon…I promise!

Fixing jQuery memory leaks in ASP.NET

July 17th, 2009

When it comes to javascript toolkits there seem to be a plethora of options but in my opinion by far the two that stand out tall amongst others are jQuery and Prototype. Although Prototype is an aged toolkit that has proven itself and extends the existing DOM functionality acting as a proxy for the available DOM objects, I am a bigger fan of jQuery due to it’s simplicity, small footprint, and it’s powerful DOM parser.

In this write-up, I assume you are using jQuery in an ASP.NET web application and have heard some Prototype enthusiasts bash it by saying it has memory leaks and are looking for an explanation of what those are and how to fix them. I will list the two that I have come across by doing various research on the web and the solutions I found that I integrated into my applications.

Both of these memory leaks are a result of asynchronous refreshes using UpdatePanel.  When an UpdatePanel refreshes, it makes a regular request to your ASPX page and refreshes only a part of the loaded page in the browser.  During this refresh and the process of throwing away existing DOM elements is when we run into these memory leaks with jQuery.

IE Garbage Collection

I found this issue at a very thorough write-up on CodeProject which explained exactly what was going on.  To give you a summary, this is what happens.  You might have jQuery scripts that parse your DOM and attach events to various elements throughout your page.  Some of these elements are likely the ones that get thrown away when an UpdatePanel refresh happens.

The problem in IE is that it has two garbage collectors that run periodically and clean out the orphaned element objects from memory but if any of those objects have events attached to them, neither garbage collector can dispose of those objects.  Given that, if you have a page with an UpdatePanel that is constantly being refreshed with elements with events attached, the memory consumption of that IE process will keep growing.

Fortunately, before an UpdatePanel refresh happens and the old DOM elements are thrown away, the ASP.NET client side library checks each element for a dispose method and invokes that for the element to clean away any resources.  jQuery also bind to the window.unload event providing for doing clean up before the user leaves a page.  However, since jQuery doesn’t know anything about the UpdatePanel we have to make that connection between the two by taking advantage of jQuery’s plugin support and ASP.NET PageRequestManager class’ events.

Here is the jQuery plugin code:

(function($) {
    $.fn.disposable = function(cln) {
        return this.each(function() {
            var el = this;
            if (!el.dispose) {
                el.dispose = cleanup;
                $(window).bind("unload", cleanup);
            }
            function cleanup() {
                if (!el) return;
                $(el).unbind();
                $(window).unbind("unload", cleanup);
                el.dispose = null;
                el = null;
            };
        });
    };
})(jQuery);

Now, anytime you retrieve jQuery elements in your scripts and plan to attach events to them, simply call disposable on them so that they are wired up to be properly disposed as follows:

$(':submit').click(function() {
    // do something here
}).disposable();

jQuery.Data()

jQuery has a very neat feature for you to be able to store metadata on an element using the data(key, value) method on an element instance.  The problem is that if you clear contents of a DIV by doing .innerHTML = “” that contains elements that have data associated with them, the data will be orphaned and live in memory eventually causing memory leaks.

It also just so happens that when an UpdatePanel refresh happens, the new content is replaced with the old content by setting the innerHTML property of the UpdatePanel element.  This becomes tricky now because UpdatePanel doesn’t know about jQuery or it’s support for setting data on DOM elements.

Thanks to a blog by Malnotna one workaround that is clean and is abstract is as follows:

1.  Save the following as a .js file:

jQuery(function(){
    if (Sys && Sys.WebForms && !Sys.WebForms.PageRequestManager.jQueryDestroyTreeOverriden) {
        Sys.WebForms.PageRequestManager.jQueryDestroyTreeOverriden = true;
        var oldFn = Sys.WebForms.PageRequestManager.prototype._destroyTree;
        var depth = 0;
        Sys.WebForms.PageRequestManager.prototype._destroyTree = function(element) {
            depth++;
            oldFn.apply(this, [element]);
            if (--depth == 0) {
                jQuery(element).empty();
            }
        }
    }
});

2. Load it on your pages after the jQuery library.

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="MSAjaxWebFormsJQueryData.js"></script>

I hope you guys find this article helpful and keep a lookout for more posts about other jQuery/MS Ajax functionality here.

Regular expression parsing in Python

July 15th, 2009

Need to fill this in…

Some code:

class Bag:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def addtwice(self, x):
        self.add(x)
        self.add(x)