1H.com 
      
     
      
       1H.com 
      
     
      
       
       
       Exploiting the Newer Perl  
       to Improve Your Plugins 
      
     
      
       Marian Marinov - mm@1h.com 
       Co-founder & CEO of 1H Ltd.

      
       AGENDA 
      
     
      
       
        
         
         
        
        
         Building feature rich plug-ins the easy way 
        
        
         Queuing for the masses 
        
        
         Cache me please

      
       $  $$  $$$  $$  $ 
      
     
      
       
       If you rate my survey, I'll hook you up with $20 cPCache $$$. 
       
       Go to this address to take the survey: 
       http://go.cpanel.net/b27 
       
       and come up to the podium once you've completed it.

      
       Plug-ins creation 
      
     
      
       
        
         
         
        
        
         jQuery 
        
        
         JavaScript::Packer 
        
        
         JSON::XS

      
       cPanel plug-ins with jQuery 
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use JQuery::Demo; 
       use JQuery::CSS; 
       use CGI; 
       
       package main; 
       my $tester = new JQuery::Demo; 
       $tester->run; 
       
       package JQuery::Demo; 
       use JQuery::Tabs;

      
       cPanel plug-ins with jQuery 
      
     
      
       
       
       sub start { 
       my $my = shift; 
       my $q = new CGI; 
       $my->{info}{TITLE} = "Tabs"; 
       my $jquery = $my->{jquery}; 
       my @tabs = ("tab 1","tab 2","tab 3","tab 4"); 
       my @texts = ("line 1","line 2","line 3","line4");

      
       cPanel plug-ins with jQuery 
      
     
      
       my $tab = JQuery::Tabs->new(id => 'myTab', 
       addToJQuery => $jquery, 
       tabs => \@tabs, 
       remote => 'true',  
       remoteProgram => 'jquery_tabs_results.pl', 
       rm => 'myMode', 
       spinner => 1 ); 
       my $html = $tab->HTML; 
       $my->{info}{BODY} = qq[<h1>START OF TAB EXAMPLE</h1>$html</div>END OF EXAMPLE</h1>]; 
       }

      
       cPanel plug-ins with jQuery

      
       JavaScript::Packer 
      
     
      
       $ wc -l uncompressed.js  
       1078 uncompressed.js 
       $ ls -l uncompressed.js  
       -rw-r--r-- 1 hackman hackman 31609 Oct  8 00:43 uncompressed.js 
       $ ./minify-js.pl  
       $ ls -l compressed.js  
       -rw-rw-r-- 1 hackman hackman 15847 Oct  8 00:43 compressed.js 
       $ wc -l compressed.js  
       0 compressed.js

      
       JavaScript::Packer 
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use JavaScript::Packer; 
       my $packer = JavaScript::Packer->init(); 
       open( UNCOMPRESSED, 'uncompressed.js' ); 
       open( COMPRESSED,  '>compressed.js' ); 
       my $js = join( '', <UNCOMPRESSED> ); 
       $packer->minify( \$js, { compress => 'best' }); 
       print COMPRESSED $js; 
       close(UNCOMPRESSED); 
       close(COMPRESSED);

      
       Why JSON and why JSON::XS 
      
     
      
       
        
         
         
        
        
         We need to transfer data 
        
        
         XML is EVIL 
        
        
         The best format with the least overhead 
        
        
         The XS version is obviously faster

      
       Example with JSON 
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use JSON::XS; 
       my %res = ( 'a' => 'line1', 'b' => 'line2' ); 
       my $json = JSON::XS->new->ascii->pretty->allow_nonref; 
       print $json->encode(\%res); 
       
       $ ./json-ex.pl  
       {&quot;a&quot;:&quot;line1&quot;,&quot;b&quot;:&quot;line2&quot;}

      
       Why queuing is helpful 
      
     
      
       
        
         Performance 
         
          
           No need to handle your own forks 
          
          
           Queing slow commands 
          
          
           The data is &quot;HOT&quot;  
          
         
        
        
         Concurrency 
         
          
           &quot;HOT&quot; connections 
          
          
           No need to think about the position in a file 
          
         
        
        
         Security 
         
          
           You have to encode and check the data sent to the functions

      
       Introduce Queuing 
      
     
      
       
        
         
         
        
        
         Gearman - http://gearman.org 
        
        
         RabbitMQ - http://www.rabbitmq.com

      
       Gearman Architecture 
      
     
      
       
        
         Server - handles the queues  
        
        
         Client - adds requests to the queue 
        
        
         Worker - handles requests from the queue 
        
       
      
     
      
       Worker 
      
     
      
       Client 
      
     
      gearmand 
      
       
       
       
       
       
       
      
     
      Web App 
      
       
       
       
       
       
       
      
     
      Daemon

      
       Gearman client 
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use Gearman::Client; 
       my $client = Gearman::Client->new; 
       $client->job_servers('127.0.0.1:4730'); 
       $str = &quot;my client has called&quot;; 
       eval { 
       local $SIG{ALRM} = sub { die 'timeout'; }; 
       alarm(3); 
       $client->dispatch_background('log_me', $str); 
       alarm(0);  
       };

      
       Gearman worker 
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use Gearman::Worker; 
       use POSIX qw(strftime); 
       $logfile = '/home/hackman/test.log'; 
       open LOG, '>>', $logfile; 
       select((select(LOG), $| = 1)[0]); 
       my $logger = sub { ... }; 
       my $w = Gearman::Worker->new; 
       $w->job_servers('127.0.0.1:4730'); 
       $w->register_function( log_me => $logger ); 
       $w->work while 1;

      
       Gearman setup 
      
     
      
       # make && make install 
       # gearmand -d -u gearman -p 4730 
       
       # gearman_status.pl  
       function name  queue  exec worker 
       log_me  1  1  1 
       check_oneh  0  0  1 
       gather_child  154  72  72

      
       RabbitMQ architecture 
      
     
      RabbitMQ 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      
      
       
       
       
       
       
       
       
       
       
      
     
      
      
       
       
       
       
       
       
       
       
       
      
     
      
      
       
       
       
       
       
       
       
       
       
      
     
      
      
       
       
       
       
       
       
       
       
       
      
     
      Queue 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      Exchange 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      Server 
      
       
       
       
       
       
       
      
     
      Server 
      
       
       
       
       
       
       
      
     
      Queue 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      Server

      
       RabbitMQ architecture 
      
     
      
     
      RabbitMQ 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      AMQP 
      
       
       
       
       
       
       
      
     
      XMPP 
      
       
       
       
       
       
       
      
     
      STOMP 
      
       
       
       
       
       
       
      
     
      HTTP 
      
       
       
       
       
       
       
      
     
      AMQP 
      
       
       
       
       
       
       
      
     
      XMPP 
      
       
       
       
       
       
       
      
     
      STOMP 
      
       
       
       
       
       
       
      
     
      HTTP

      
       
        
         RabbitMQ setup 
        
       
      
     
      
       # yum install erlang 
       # rpm -Uvh rabbitmq-server-2.6.1-1.noarch.rpm 
       
       # rabbitmq-server -detached 
       # rabbitmqctl status 
       Status of node rabbit@gamelon ... 
       [{pid,6829}, {running_applications, 
       [{rabbit,&quot;RabbitMQ&quot;,&quot;2.6.1&quot;}, 
       ....

      
       
        
         RabbitMQ client 
        
       
      
     
      
       #!/usr/bin/perl -w 
       use strict; 
       use Net::RabbitMQ; 
       my $mq = Net::RabbitMQ->new(); 
       $mq->connect(&quot;localhost&quot;, { user => &quot;guest&quot;, password => &quot;guest&quot; }); 
       $mq->channel_open(1); 
       $mq->publish(1, &quot;testqueue&quot;, &quot;Hi there!&quot;); 
       $mq->disconnect();

      
       
        
         RabbitMQ server 
        
       
      
     
      
       #!/usr/bin/perl -w 
       use strict; use Data::Dumper ;  use Net::RabbitMQ; 
       my $mq = Net::RabbitMQ->new(); 
       $mq->connect(&quot;localhost&quot;,{user=>&quot;guest&quot;,password=>&quot;guest&quot;}); 
       $mq->channel_open(1); 
       $mq->exchange_declare(1, 'my_x',{auto_delete => 0}); 
       $mq->queue_declare(1, 'testqueue',{auto_delete => 0}); 
       $mq->queue_bind(1, 'testqueue', 'my_x', 'foo'); 
       while(1){ 
       my $hashref = $mq->get(1, 'testqueue'); 
       print Dumper($hashref) if (defined($hashref)); 
       }

      
       
        
         Caching 
        
       
      
     
      
       
        
         
        
        
         Why cache ? 
         
        
        
         Cache::memcached 
        
        
         Cache::Redis - written especially for this talk :)

      
       
        
         Cache::Memcached 
        
       
      
     
      
     
      memcached 
      
       
       
       
       
       
       
       
       
       
       
       
       
      
     
      CGI 
      
       
       
       
       
       
       
      
     
      CGI 
      
       
       
       
       
       
       
      
     
      CGI 
      
       
       
       
       
       
       
      
     
      CGI 
      
       
       
       
       
       
       
      
     
      CGI

      
       
        
         Cache::Redis

      
       Conclusions

      
       Questions 
      
     
      
         ?  ?  ?  ? 
       ?  ?  ?  ?    ?  ? 
       ?  ? ?  ? ?  ?  ? 
       ?    ? ?  ?    ?    ? 
       ?      ?

      
       
       Thank you 
       
       Please visit us at Booth 23 
      
     
      
       Marian Marinov - mm@1h.com 
       Co-founder & CIO at 1H Ltd. 
      
     
      
       1H.com 
      
     
      
       1H.com

      
       $  $$  $$$  $$  $ 
      
     
      
       
       If you rate my survey, I'll hook you up with $20 cPCache $$$. 
       
       Go to this address to take the survey: 
       http://go.cpanel.net/b27 
       
       and come up to the podium once you've completed it.

Exploiting the newer perl to improve your plugins

  • 1.
    1H.com 1H.com Exploiting the Newer Perl to Improve Your Plugins Marian Marinov - [email protected] Co-founder & CEO of 1H Ltd.
  • 2.
    AGENDA Building feature rich plug-ins the easy way Queuing for the masses Cache me please
  • 3.
    $ $$ $$$ $$ $ If you rate my survey, I'll hook you up with $20 cPCache $$$. Go to this address to take the survey: http://go.cpanel.net/b27 and come up to the podium once you've completed it.
  • 4.
    Plug-ins creation jQuery JavaScript::Packer JSON::XS
  • 5.
    cPanel plug-ins with jQuery #!/usr/bin/perl -w use strict; use JQuery::Demo; use JQuery::CSS; use CGI; package main; my $tester = new JQuery::Demo; $tester->run; package JQuery::Demo; use JQuery::Tabs;
  • 6.
    cPanel plug-ins with jQuery sub start { my $my = shift; my $q = new CGI; $my->{info}{TITLE} = &quot;Tabs&quot;; my $jquery = $my->{jquery}; my @tabs = (&quot;tab 1&quot;,&quot;tab 2&quot;,&quot;tab 3&quot;,&quot;tab 4&quot;); my @texts = (&quot;line 1&quot;,&quot;line 2&quot;,&quot;line 3&quot;,&quot;line4&quot;);
  • 7.
    cPanel plug-ins with jQuery my $tab = JQuery::Tabs->new(id => 'myTab', addToJQuery => $jquery, tabs => \@tabs, remote => 'true', remoteProgram => 'jquery_tabs_results.pl', rm => 'myMode', spinner => 1 ); my $html = $tab->HTML; $my->{info}{BODY} = qq[<h1>START OF TAB EXAMPLE</h1>$html</div>END OF EXAMPLE</h1>]; }
  • 8.
    cPanel plug-ins with jQuery
  • 9.
    JavaScript::Packer $ wc -l uncompressed.js 1078 uncompressed.js $ ls -l uncompressed.js -rw-r--r-- 1 hackman hackman 31609 Oct 8 00:43 uncompressed.js $ ./minify-js.pl $ ls -l compressed.js -rw-rw-r-- 1 hackman hackman 15847 Oct 8 00:43 compressed.js $ wc -l compressed.js 0 compressed.js
  • 10.
    JavaScript::Packer #!/usr/bin/perl -w use strict; use JavaScript::Packer; my $packer = JavaScript::Packer->init(); open( UNCOMPRESSED, 'uncompressed.js' ); open( COMPRESSED, '>compressed.js' ); my $js = join( '', <UNCOMPRESSED> ); $packer->minify( \$js, { compress => 'best' }); print COMPRESSED $js; close(UNCOMPRESSED); close(COMPRESSED);
  • 11.
    Why JSON and why JSON::XS We need to transfer data XML is EVIL The best format with the least overhead The XS version is obviously faster
  • 12.
    Example with JSON #!/usr/bin/perl -w use strict; use JSON::XS; my %res = ( 'a' => 'line1', 'b' => 'line2' ); my $json = JSON::XS->new->ascii->pretty->allow_nonref; print $json->encode(\%res); $ ./json-ex.pl {&quot;a&quot;:&quot;line1&quot;,&quot;b&quot;:&quot;line2&quot;}
  • 13.
    Why queuing is helpful Performance No need to handle your own forks Queing slow commands The data is &quot;HOT&quot; Concurrency &quot;HOT&quot; connections No need to think about the position in a file Security You have to encode and check the data sent to the functions
  • 14.
    Introduce Queuing Gearman - http://gearman.org RabbitMQ - http://www.rabbitmq.com
  • 15.
    Gearman Architecture Server - handles the queues Client - adds requests to the queue Worker - handles requests from the queue Worker Client gearmand Web App Daemon
  • 16.
    Gearman client #!/usr/bin/perl -w use strict; use Gearman::Client; my $client = Gearman::Client->new; $client->job_servers('127.0.0.1:4730'); $str = &quot;my client has called&quot;; eval { local $SIG{ALRM} = sub { die 'timeout'; }; alarm(3); $client->dispatch_background('log_me', $str); alarm(0); };
  • 17.
    Gearman worker #!/usr/bin/perl -w use strict; use Gearman::Worker; use POSIX qw(strftime); $logfile = '/home/hackman/test.log'; open LOG, '>>', $logfile; select((select(LOG), $| = 1)[0]); my $logger = sub { ... }; my $w = Gearman::Worker->new; $w->job_servers('127.0.0.1:4730'); $w->register_function( log_me => $logger ); $w->work while 1;
  • 18.
    Gearman setup # make && make install # gearmand -d -u gearman -p 4730 # gearman_status.pl function name queue exec worker log_me 1 1 1 check_oneh 0 0 1 gather_child 154 72 72
  • 19.
    RabbitMQ architecture RabbitMQ Queue Exchange Server Server Queue Server
  • 20.
    RabbitMQ architecture RabbitMQ AMQP XMPP STOMP HTTP AMQP XMPP STOMP HTTP
  • 21.
    RabbitMQ setup # yum install erlang # rpm -Uvh rabbitmq-server-2.6.1-1.noarch.rpm # rabbitmq-server -detached # rabbitmqctl status Status of node rabbit@gamelon ... [{pid,6829}, {running_applications, [{rabbit,&quot;RabbitMQ&quot;,&quot;2.6.1&quot;}, ....
  • 22.
    RabbitMQ client #!/usr/bin/perl -w use strict; use Net::RabbitMQ; my $mq = Net::RabbitMQ->new(); $mq->connect(&quot;localhost&quot;, { user => &quot;guest&quot;, password => &quot;guest&quot; }); $mq->channel_open(1); $mq->publish(1, &quot;testqueue&quot;, &quot;Hi there!&quot;); $mq->disconnect();
  • 23.
    RabbitMQ server #!/usr/bin/perl -w use strict; use Data::Dumper ; use Net::RabbitMQ; my $mq = Net::RabbitMQ->new(); $mq->connect(&quot;localhost&quot;,{user=>&quot;guest&quot;,password=>&quot;guest&quot;}); $mq->channel_open(1); $mq->exchange_declare(1, 'my_x',{auto_delete => 0}); $mq->queue_declare(1, 'testqueue',{auto_delete => 0}); $mq->queue_bind(1, 'testqueue', 'my_x', 'foo'); while(1){ my $hashref = $mq->get(1, 'testqueue'); print Dumper($hashref) if (defined($hashref)); }
  • 24.
    Caching Why cache ? Cache::memcached Cache::Redis - written especially for this talk :)
  • 25.
    Cache::Memcached memcached CGI CGI CGI CGI CGI
  • 26.
    Cache::Redis
  • 27.
    Conclusions
  • 28.
    Questions ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
  • 29.
    Thank you Please visit us at Booth 23 Marian Marinov - [email protected] Co-founder & CIO at 1H Ltd. 1H.com 1H.com
  • 30.
    $ $$ $$$ $$ $ If you rate my survey, I'll hook you up with $20 cPCache $$$. Go to this address to take the survey: http://go.cpanel.net/b27 and come up to the podium once you've completed it.

Editor's Notes

  • #2 \n \n \n \n \n \n
  • #3 \n \n \n \n \n
  • #4 \n \n \n \n \n
  • #5 \n \n \n \n \n
  • #6 \n \n \n \n \n \n
  • #7 \n \n \n \n \n @tabs – name of the tabs \n @texts – tabs contents \n \n \n
  • #8 \n \n \n \n \n header - start of tab example \n footer – end of tab example \n combine this with HTML::Template or Template::Toolkit \n \n \n
  • #9 \n \n \n \n \n
  • #10 \n \n \n \n \n
  • #11 \n \n \n \n \n
  • #12 \n \n \n \n \n
  • #13 \n \n \n \n \n
  • #14 \n \n \n \n \n
  • #15 \n \n \n \n Who is using gearman: \n LiveJurnal \n Booking.com \n \n Who is using RabbitMQ: \n JPMorgan \n Goldman Sachs \n Cisco \n Novell \n Microsoft \n RedHat \n \n \n \n
  • #16 \n \n \n \n \n
  • #17 \n \n \n \n \n
  • #18 \n \n \n \n \n
  • #19 \n \n \n \n \n
  • #20 \n \n \n \n \n
  • #21 \n \n \n \n AMQP - Advanced Message Queuing Protocol \n STOMP - Streaming Text Oriented Messaging Protocol \n XMPP - Extensible Messaging and Presence Protocol \n \n \n \n
  • #22 \n \n \n \n \n
  • #23 \n \n \n \n \n
  • #24 \n \n \n \n \n
  • #25 \n \n \n \n \n
  • #26 \n \n \n \n \n
  • #27 \n \n \n \n \n
  • #28 \n \n \n \n Premature optimizations are infecting all of us \n \n Wrongly implemented algorithms or usage of things like for/foreach when you can use while are clear performance hogs. \n \n \n
  • #29 \n \n \n \n \n
  • #30 \n \n \n \n \n
  • #31 \n \n \n \n \n