Monday, February 11, 2013

Some thoughts on MongoDB Nodejs driver

I am in the process of evaluating mongoDB for one of the product requirements. We were on the J2EE stack and MongoDB has java driver with which we got awesome results compared to the existing framework in terms of not only speed and resource utilization but also in terms data replication and fail-over behavior.

I was curious about mongoDB nodejs driver and tried to test its performance over java driver. It was very easy to write code as I was already familiar with javascript and the footprint, startup time are far less compared to the J2EE stack.

Now comes the real problem with NodeJS. My application typically tries to connect to different database for each request and existing nodejs api does not support to use same driver across different requests rendering the connection pooling offered by the framework useless !!!. I need to create server instance for each request.

With  read preference as NEAREST, the reads are not shared across the replica set members and only the member on which my nodejs is running is being hit resulting in performance degradation compared to my existing framework.

Here is the stackoverflow question raised regarding the same issue.

Think twice before planning to use nodejs driver. 

Monday, January 28, 2013

MongoDB index completion status

MongoDB allows you to create indexes and run them in the background using the ensureIndex. Often indexing is a time consuming process and may take long if indexed upon string and the collection contains millions of records. For example, Indexing on my collection having 50 million records took almost 15 minutes. Here is the script that can be used to monitor index operation status.


var ops = db.currentOp();

if(ops.inprog && ops.inprog.length > 0) {
    for(o in ops.inprog) {
        var op = ops.inprog[o];
        if(op.msg && op.msg.match(/bg index build/)) {
            print(op.opid+' - '+op.msg);
        }
    }
}

copy above code into test_index_status.sh, execute mongo index_status.sh and see the magic!!!



Monday, October 29, 2012

Configuring jawr to use YUI compressor instead of JSMinifier for minifying js files

Jawr is the framework that is developed to make the versioning, compression, minifying css, js files  more stream lined. It can also be integrated with smartsprites and people can write their custom handlers for their application needs. I am not here to explain about various features supported by jawr. Please go to the link mentioned above for more details.

JSMin is the default post processor used by jawr, it is too old, does not understand some semantics and bothers you throwing errors during minifying process, or the minified version has some bugs which are not present if you set debug mode to true.

So the other option is YUI Compressor,  Jawr identifies which post processor to use based on jawr.js.bundle.factory.bundlepostprocessors property in jawr.properties it is defaulted to JSMin if none is specified. We can set the property to YUI to notify jawr to use YUI compressor instead. Download YUI Compressor from http://yuilibrary.com/download/builder/ please use latest version 2.4.7 as the previous versions has some class loading issues with Rhino.  Do not include rhino in your application's lib directory to avoid conflicts with the same namespace used by both the jars.

Your jawr.properties will look something like this.


# Common properties
jawr.debug.on=false
jawr.gzip.on=true
jawr.gzip.ie6.on=false
jawr.charset.name=UTF-8
jawr.js.bundle.factory.bundlepostprocessors= YUI

Compile, make war and deploy it on the server and see that previously thrown js errors were gone and application runs smoothly. Let me know if you find any difficulty in configuring it.

Friday, June 22, 2012

CORS issues with IE9 and workarounds

CORS(Cross-Origin-Resource-Sharing) is one of the features in HTML5 feature stack that enables a page to make AJAX requests to other domains. This feature is introduced to circumvent the Same-Origin-Policy. I am not discussing about CORS in detail here as there are lots of online resources available.

I am working on a product where html files are served from one domain and back-end requests should be made to another domain (of course sub-domain) for security reasons and API clarity.

Luckily we need to support browsers with HTML5 capabilities like Chrome > 14, Safari  > 5.0.5 , Firefox > 9, IE >8. I thought that IE9 is HTML5 complaint and promised to have support for it. I could have investigated a little bit 

Application was implemented and we are running for release. Suddenly while going through entire flow we realized that IE9 is not making any CORS requests. From then on our hunt started. Searching blogs, articles, stackoverflow for solutions.

I am here to explain the steps we following to resolve IE9 CORS issues. We need to modify quite a bit on server side also to suport IE9 CORS.

I found an interesting blog about limitations in IE9 CORS and work arounds.
Here is the http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

IE9 uses a special object called XDomainRequest for making CORS requests and this is used in IE8 and IE9. Fortunately they realized developers problems and started supporting HTML5 CORS spec in IE10. Hope these problems wont happen in IE10 (not tested yet).

JQuery for some reason did not support XDomainRequest as it is not going to live long. Instead plugin was developed and it pretty much the one that fits the situation. You can find the plugin at http://viejs.org/docs/2.0.0alpha1/xdr.html.

We need to modify that js file a bit by adding before or after one of the handlers.

xdr.onprogress = function() { }; 

Please remember to add it otherwise IE9 will not make any CORS request.

Browser wont send any cookie information for CORS requests hence we should send auth-info as query param and handle it on server side. Even browser wont honor Set-Cookie header in the response of CORS requests and we can handle it by using the same query param logic on the client side. Get the auth-info as query param from the server and set is as cookie on client side.


Browser only supports GET, POST methods for CORS. For this we need to deviate from REST methodology of using PUT, DELETE based on the requirements. Should modify server code to support both PUT, POST for the end-point. We can ditch POST once we stop supporting IE9 in near future.

Browser wont send any custom headers set in the CORS request. For POST methods no other Content-Type is supported other than text/plain. We should modify the server code to handle POST requests without content type.

Hope I explained something that makes sense for those who are struggling with IE9 CORS.








Friday, May 13, 2011

Difference in core javascript and jquery event handling

I was surprised to see that jquery handles events in a different way as compared to core javascript event handling.

Here is the case

jQuery("#testAnchor").click(function() {
//do some thing
return false;
});

If you are returning false in an event handler in jquery, that means you are stopping propagation and preventing default. All the handlers listening on the click event on that element will be called and the event will not be propagated to the parent element.

If you use

document.getElementById("testAnchor").onclick = function(event) {
event = event || window.event;
//do some thing
return false;

returning false in this case wont stop propagating the event. we should indeed say event.cancelBubble= true or event.stopPropagation() based on the browser.

Knowing whether control key is pressed while an event happened

If you are listening to click events of anchors to do some operation of showing a dialog or doing something else, you have to know whether ctrl key is pressed or not as you may not want your custom logic to kick in when ctrl key is pressed as user wants to open the link in the new tab.

He is the solution, assuming jquery is used
jQuery("a.link").click(function(event) {
if(event.metaKey || event.ctrlKey) {
//ctrl key is pressed
}
});

checking for metaKey apart from ctrlKey property of event as mac's command key press will set metaKey property to true and ctrlKey for remaining browsers.

Knowing whether a javascript code is being executed inside an iframe

Sometimes it is required to know whether the code is being executed inside an iframe or not.

Following code works for all browsers.

var inIframe=false;

try {
inIframe = window.top.document == document;
}catch(ex) {
inIframe = true;
}

The reason for keeping try catch in the above logic is when ever window.top.document is accessed and if that document belongs to different domain, then IE throws Access Denied error.