Tuesday, October 25, 2011

TSG HTML5 Class Part 1

Thanks everyone for attending the TSG HTML5 Class Part 1.

Here is the link to the presentation tonight

If you want to read more about HTML5 new elements, here is the link

[ Reading for this week if you have time ]
Difference between DIV, SECTION and ARTICLE
http://boblet.tumblr.com/post/130610820/html5-structure1

Please finish your homework if possible, see you all next week!

Feel free to ask any question either in email list or in this blog post.

Thursday, October 20, 2011

Parallel Processing benchmark in PHP ( CURL version )

Introduction
There are so many tools that gives PHP the capabilities of parallel processing.  Well, not multiple threads, but multiple processes, the outcome is very similar though, it makes PHP do several things at the same time without blocking.

Tools you can find today that I can think of :-
  • Gearman
  • Fork (pcntl_fork)
  • curl_multi
  • rolling curl ( just another flavor of curl_multi )
  • various Message Queue, like Rabbit MQ.

But this post is focusing on comparing / benchmarking "curl_multi" and "rolling curl",  since in general "rolling curl" is believed to be more efficient than "curl_multi" without doing the rolling. However, the benchmark result is quite confusing me.

Note: "Rolling Curl" at the end is still using curl_multi, but the difference is it swap out (roll out) finished job instead of waiting for the longest job to return.  For example, in this way, you don't need to wait for everything to finish before processing your returned data.

Benchmark Starts Here
I'm trying to do a benchmark between using Rolling Curl v.s. normal implementation of curl_multi (without the rolling).  The result is very close, but quite a number of time it shows that Rolling Curl is actually slower.

What I did is having both doing the same thing, "curl" 20 different urls and count 0 to 500 after the job is done. I try to simulate 5 concurrent users to call the script for 10 times.   And here is the result I get back.

Rolling Curl

Transactions:            50 hits
Availability:        100.00 %
Elapsed time:         44.57 secs
Data transferred:         0.00 MB
Response time:          4.08 secs
Transaction rate:         1.12 trans/sec
Throughput:          0.00 MB/sec
Concurrency:          4.58
Successful transactions:          50
Failed transactions:            0
Longest transaction:         9.54
Shortest transaction:         1.78

curl_multi without rolling

Transactions:            50 hits
Availability:        100.00 %
Elapsed time:         39.11 secs
Data transferred:         0.00 MB
Response time:          3.51 secs
Transaction rate:         1.28 trans/sec
Throughput:          0.00 MB/sec
Concurrency:          4.49
Successful transactions:          50
Failed transactions:            0
Longest transaction:         8.96
Shortest transaction:         1.94

At first I'm thinking the Rolling Curl will be faster since it will do the counting whenever a particular "curl" is done and rolled out.  However, it looks like the benchmark is telling us that it is faster without rolling the curl.  The following is the testing script I'm using to compare with Rolling Curl.

Is there something I'm missing when I use this testing script??  Any thoughts??



// testing function
function multiple_curl_request($nodes){ 
        $mh = curl_multi_init(); 
        $curl_array = array(); 
        foreach($nodes as $i => $url) 
        { 
            $curl_array[$i] = curl_init($url); 
            curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true); 
            curl_multi_add_handle($mh, $curl_array[$i]); 
        } 
        $running = NULL; 
        do { 
            usleep(1000); 
            curl_multi_exec($mh,$running); 
        } while($running > 0); 
        
        $res = array(); 
        foreach($nodes as $i => $url) 
        { 
            $res[$url] = curl_multi_getcontent($curl_array[$i]); 
            for($i = 0; $i < 500; $i++) {
                // just counting and do nothing
            }
        } 
        
        foreach($nodes as $i => $url){ 
            curl_multi_remove_handle($mh, $curl_array[$i]); 
        } 
        curl_multi_close($mh);        
        return $res; 
} 



Reply from Josh ( Author of Rolling Curl )
I bench marked Rolling Curl when I first wrote it and it was significantly faster.  Of course, since you're measuring things on the open web, there are lots of variables that come into play...  is the network just slow, are you overloading your own server, etc.  Keep in mind, the benefits of rolling curl mostly show up when you are dealing with large data sets.

I'd be interested to see the full code you used for your bench mark, although I won't have time to debug it for you.  

For a good benchmark, I would suggest you download the Alexia top 1,000 sites using regular curl_multi and compare the results with downloading the same list using rolling curl.  I think you will see the difference -- ie. regular curl_multi will probably choke on you.

Thursday, October 13, 2011

jQuery Plugin Patterns

Here are some jQuery Plugin Patterns, the list is still expanding.  This post is mostly for my own reference, but just blog it here in case someone might be helped from this.

One note before you start doing your super fancy plugin.  The 'this' keyword in the immediate scope of the plugin is referring to the jQuery object, so there is no need to do $(this).  


Basic Form


  $.fn.yourPlugin = function(options, callback) {
    // ...
  };



Wrapped in Closure to create namespace

;(function($, window, undefined) {
  $.fn.yourPlugin = function(options, callback) {
    // ...
  };
})(jQuery, window);



Define multiple related functions (or related plugins) in one shot. 

;(function($, window, undefined) {
  $.extend($.fn, {
     yourPlugin: function() {
        // ...
     },
     yourSecondPlugin: function() {
        // ...
     }
  });
})(jQuery, window);


Prototype way

;(function($, window, undefined) {
  var pluginName = 'yourPlugin', pluginDefaultOptions = {};

  function Plugin(el, options) {
    this.element = el;
    this.options = $.extend({}, pluginDefaultOptions, options);
    this._name = pluginName;
    this.init();
  }  

  Plugin.prototype.init = function() {
    // ...
  }

  // make sure only one instance is instantiated
  $.fn[pluginName] = function ( options ) {
    return this.each(function () {
       if (!$.data(this, 'plugin_' + pluginName)) {
           $.data(this, 'plugin_' + pluginName,
           new Plugin( this, options ));
       }
    });
  }

})(jQuery, window);


Object Literal way

;(function($, window, undefined) {

    $.fn.pluginName = function(method) {

        var methods = {
            init : function(options) {
                this.pluginName.settings = $.extend({}, 
                                             this.pluginName.defaults, 
                                             options);
                return this.each(function() {
                    var $element = $(this), 
                         element = this;  
                    // ...
                });
            },

            my_public_method: function() {
                // ...
            }
        }

        var helpers = {
            my_private_method: function() {
                // ...
            }
        }

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error( 'Method "' +  method + '" does not exist in pluginName plugin!');
        }
    }

    $.fn.pluginName.defaults = {
        foo: 'bar'
    }

    $.fn.pluginName.settings = {}

})(jQuery, window);



Modified Object Literal way

;(function($, window, undefined){
    $.fn.packagename = function(options, callback){
        
        var params = $.extend({},
                        $.fn.packagename.default_options, options), 
                        $that = $(this);
        
        if($.isFunction(options)){
            callback = options;
            options = {};
        } 
        
        var methods = {
            init: function() {
               // ... 
            }
        }
        
        methods.init.apply(this,[]);      
    }
    
    $.fn.packagename.default_options = {
       src: ".data" 
    }
})(jQuery, window);






Wednesday, October 12, 2011

Caching with Memcache and APC

If you are doing PHP, you should be knowing what is cache and different type of cache strategies.  I bumped into this slides when I was comparing (or precisely documenting) different type of cache strategies.  This slide is focusing on Memcahe and APC, and when/why/how to use them.


Friday, October 7, 2011

How to hack Apache Server

Got an internal email about a "security thread" in Apache Server, and someone send me this link as well.


Thursday, October 6, 2011

Dump Your "clear:both", an Alternative to Clearing Floats

One of the traditional ways to solve the clearing floats problem is by adding an extra element and make it "clear:both".

<div style="clear:both" />

However this method has some draw backs :-
  1. The clear both contributes nothing meaningful to the markup besides it's used to fix a floating issue.
  2. It adds extra bits to your html code.
...
Let me show you another way of solving this problem without using an extra markup, the only thing you need to do is :-
  1. In your css where your container that contained the float elements, add
    • min-width ( or width or height )
    • overflow:hidden
That's all you need.  Well, I know if is not very intuitive, and if you still don't understand what I'm talking about,  here is the example, http://cssdesk.com/ZwJ7x.

Let me know your thoughts!

Note: Oh, btw, I believe everyone is using "clearfix" nowadays, it seems to be a standard method in the industry.  And I brought it up in this post is just in case someone out there is still using <div style="clear:both"> .


Monday, October 3, 2011

TSG HTML5 Class for Beginners


Want to learn the current hottest buzz in web development - HMTL5 ??  Yes , it is very hot out there now!!





I will be teaching an HTML5 class for Beginners.  I will cover HTML5 new elements, CSS3 and  javascript API ( e.g, canvas, geo-location and more ).  For more details, please visit their website.  You should see HTML5 in their "Current Classes" section.

Please go to TSG website to register if you are interested.

Date & Place

10/25, 11/1,8,15,22 total 5 meets from 7:30 pm to 9:30pm at G10, ROLCC

Course Detail

  1. HTML5, CSS3 Introduction and Survey
  2. New HTML5 elements and Structuring a page
  3. Dwelling Deeper in CSS3
  4. HTML5 javascript APIs introduction
  5. Projects Demo, and what other thing you should know before going to interview
Each Session will have 30 mins hands on practice lab, so please do bring your laptop. This course is trying to get you understand the basic of HTML5 stack and how the industry is utilizing this hot tech buzz currently. It will be helpful if you have basic experience in HTML and CSS, but not required. See you there!





Saturday, October 1, 2011

What will be the gift this year?

Every year God will give me a gift around my birthday, wonder what He will give me this year?  I'm looking forwarded to that.  Thanks God.  I still remember the gift He gave me for every year, and I'm very thanksgiving for that.

I praised God for His providence.