SlideShare a Scribd company logo
1 of 27
Gearman Job Queue.
Раскрываем недокументированные возможности
Синхронное выполнение задач


  Client   Client   Client   Client   Client   Client   Client




                             Task
Без очередей — хаос!
Очереди к ограниченным ресурсам необходимы!




                             ●   Пред-расчет данных
                             ●   Операции импорта/экспорта данных
                             ●   Обработка логов системы
                             ●   Маркетинговый анализ базы данных
                             ●   Почтовые рассылки
                             ●   Map/Reduce
                             ●   и многое другое...
Выполнение задачи в асинхронном режиме
              Client                Job Server             Worker




                        add job
                       job handle
                                                 execute




                                                 success
Client   Client     Client
                     Client      Client   Client
                      Client




                  Task manager




Worker   Worker     Worker       Worker   Worker
About project Gearman

           Gearman = Manager

           2005: originally Perl implementation by Danga Interactive
           2008: rewrite in C by Brian Aker

           Used in:
                Digg (45+ servers, 400K jobs/day)
                Yahoo (60+ servers, 6M jobs/day)
                Xing.com
                Grooveshark
                ...
Преимущества и недостатки



●   Высокая скорость             ●   Мониторинг, администрирование
●   Масштабируемость             ●   Слабая документация
●   Балансировка нагрузки        ●   Работа с памятью
●   Параллельное и асинхронное   ●   Отличия API в различных версиях
    выполнение задач
●   Защита от потери очереди
●   Multi-language API
Gearman server monitoring


              Administrative Protocol
                    > telnet localhost 4730
                    > Trying ::1...
                    > Connected to localhost.
                    > Escape character is '^]'.
                    > wokers
                    FD IP-ADDRESS CLIENT-ID : FUNCTION
                    > status
                    FUNCTION TOTAL RUNNING AVAILABLE_WORKERS

              GearUp: Gearman based monitoring service
              https://launchpad.net/gearup

              Mod Gearman
              http://labs.consol.de/nagios/mod-gearman/
Client   Client         Client            Client        Client   Client


           Client API                              Client API


          Gearman                                  Gearman

           Worker API                              Worker API




Worker     Worker                Worker            Worker        Worker
client.php

             <?php
                # create our object
                $client= new GearmanClient();

                  # add the default server
                  $client->addServer();

                  $workload = array(
                      'email' => 'nobody@example.com' ,
                      'subject' => 'the subject' ,
                      'message' => 'the message'
                  );

                  # send email
                  $client->doBackground( "send_mail" , json_encode($workload));

                  if ($client->returnCode() != GEARMAN_SUCCESS) {
                      echo "bad return coden" ;
                      exit;
                  }
             ?>
worker.php

             <?php
                # create the worker
                $worker = new GearmanWorker();

                  # add the default job server (localhost)
                  $worker->addServer();

                  # add the reverse function
                  $worker->addFunction( "send_mail" , "sendMail" );

                  # start to worker listening for job submissions
                  while ($worker->work());

                  function sendMail($job)
                  {
                      $arg = json_decode($job->workload(), true);
                      mail($arg[ 'email'], $arg[ 'subject' ], $arg[ 'message' ]);
                      echo "email has been sentn" ;
                  }
             ?>
Client                Gearman                    Worker             Task

                                register tasks
                                   work()


         doBackground()
                                  run task                execute




                                                          success
worker.php
   <?php
           #...

           function sendMail($job)
           {
               $arg = json_decode($job->workload(), true);

               # connect to remote service
               $mail = new Mail($arg['email'], $arg['subject'], $arg['message']);

                  # send email
                  if (!$mail->send()){

                      # it needs to be solved

               } else {
                   echo "email has been sentn";
               }
           }
   ?>
Client                Gearman              Worker             Task




         doBackground()
                                run task            execute




                                                    failure


                                                    ???
worker.php
     <?php
             #...

             function sendMail($job)
             {
                 #...

                    # send email
                    if (!$mail->send()){

                       sleep(20);
                       $client= new GearmanClient();
                       $client->addServer();
                       $client->doBackground("send_mail", $job->workload());
                       echo "error has happened n";

                 } else {
                     echo "email has been sentn";
                 }
             }
     ?>
Client                Gearman                Worker             Task
         doBackground()         run task              execute

                                                                  sleep(20)
                            doBackground()
                                                      failure


                                run task              execute

                                                                  sleep(20)
                            doBackground()
                                                      failure


                                run task              execute

                                                      success
worker.php

         <?php
                 #...

                 function sendMail($job)
                 {
                     #...

                        # send email
                        if (!$mail->send()){

                            setCron("send_mail", $job->workload(), 20);
                        echo "error has happened n";

                     } else {
                         echo "email has been sentn";
                     }
                 }
         ?>
Client                Gearman                Worker              Task                  Cron
         doBackground()         run task              execute

                                                       failure          do postponed


                                                                                         delay
                            doBackground()

                                run task              execute
                                                                        do postponed
                                                      failure

                                                                                         delay
                            doBackground()

                                run task              execute

                                                      success           do postponed
Solution

                                                       Credit:




— In ver. 0.20 added when_to_run tasks functionality
— But public API doesn't support that functionality
— Neither does PECL Gearman module
— Documentation also is silent about it


                                                       John Ewart
                                                       Software Engineer
worker.php
     <?php
        #...

          function sendMail($job)
          {
              #...

               # send email
               if (!$mail->send()){

                  $client= new GearmanClient();
                  $client->addServer();
                  $time = time() + 20;
                  $client->doSuspended("send_mail", $job->workload(), NULL, $time);
                  echo "error has happened n" ;

              } else {
                  echo "email has been sentn" ;
              }
          }
     ?>
Suspended task execution
         Client                Gearman                   Worker             Task
                  doBackground()           run task               execute
                                         doSuspended()
                                                                  failure

                              delay


                                           run task               execute
                                         doSuspended()
                                                                  failure

                              delay

                                           run task               execute

                                                                  success
client.php


        <?php
            $client= new GearmanClient();
            $client->addServer();

             $workload = array('value' => 1, 'limit_attempts' => 3);

             $client->doBackground( "remote_procedure_call", json_encode($workload));

             if ($client->returnCode() != GEARMAN_SUCCESS) {
                 echo "bad return coden" ;
                 exit;
             }
        ?>
worker.php
       <?php
           #...
           $worker->addFunction( 'remote_procedure_call' , 'rpcJobHandler' );
           while ($worker->work());

            function rpcJobHandler($job)
            {
                $args = json_decode($job->workload(), true);
                try {    // Execute task
                    remoteProcedureCall($args[ 'value']);
                } catch (Exception $e) {
                    echo "Failure, reason: " . $e->getMessage() . "n";
                }
            }

            function remoteProcedureCall(&$value)
            {   // Accept value only less than 3
                if ($value < 3) {
                    $value++;
                    throw new Exception ("Service is unavailable" );
                }
            }
       ?>
worker.php — break of task loop
<?php
    #...
    function rpcJobHandler($job)
    {
        $args = json_decode($job->workload(), true);
         try {
             remoteProcedureCall($args[ 'value']);
        } catch (Exception $e) {
             if (!isset($args['attempt' ])) $args[ 'attempt' ] = 0;
             if (empty($args['limit_attempts' ]) or $args['attempt' ] <= $args[ 'limit_attempts' ]) {
                 $client = new GearmanClient();
                 $client->addServer();
                 if (method_exists($client, 'doSuspended' )) {
                     $time = getExecutionTime($args['attempt' ]);
                     $args[ 'attempt' ]++;
                      $client->doSuspended('run', json_encode($args), null, $time);
                 }
             } else {
                 echo "Failure, reason: " . $e->getMessage() . "n";
             }
        }
    }
?>
Geometric progression
                    <?php
                        #...
                        function getExecutionTime($attempt)
                        {
                             return time() + pow(2, (int)$attempt) * 10;
                        }
                    ?>



attempt   seconds    delta time
0         10         10s
1         20         20s
2         40         40s
3         80         1m 20s
4         160        2m 40s
5         320        5m 20s
6         640        10m 40s
7         1280       21m 20s
8         2560       42m 40s
9         5120       1h 25m 20s
10        10240      2h 50m 40s
Q &A

More Related Content

What's hot

Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)BoneyGawande
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)BoneyGawande
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShellSalaudeen Rajack
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendKirill Chebunin
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in reactBOSC Tech Labs
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupKacper Gunia
 
Persistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery PromisesPersistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery PromisesRay Bellis
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service ManagerChris Tankersley
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8Dhaval Dalal
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaExoLeaders.com
 

What's hot (20)

Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
 
Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
React lecture
React lectureReact lecture
React lecture
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friend
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Practical Celery
Practical CeleryPractical Celery
Practical Celery
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
Persistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery PromisesPersistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery Promises
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
 
Why ruby
Why rubyWhy ruby
Why ruby
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 

Similar to Gearman jobqueue

Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
Gearmanpresentation 110308165409-phpapp01
Gearmanpresentation 110308165409-phpapp01Gearmanpresentation 110308165409-phpapp01
Gearmanpresentation 110308165409-phpapp01longtuan
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanIssac Goldstand
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairMark
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your BrowserBig Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browsergethue
 
Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run themFilipe Ximenes
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScriptChengHui Weng
 
オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)Takayuki Goto
 
GPerf Using Jesque
GPerf Using JesqueGPerf Using Jesque
GPerf Using Jesquectoestreich
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job Queue
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job QueueTask Scheduling and Asynchronous Processing Evolved. Zend Server Job Queue
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job QueueSam Hennessy
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Codemotion
 

Similar to Gearman jobqueue (20)

Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
Gearmanpresentation 110308165409-phpapp01
Gearmanpresentation 110308165409-phpapp01Gearmanpresentation 110308165409-phpapp01
Gearmanpresentation 110308165409-phpapp01
 
Introdução a worker 2.0
Introdução a worker 2.0Introdução a worker 2.0
Introdução a worker 2.0
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & Gearman
 
Fabric Python Lib
Fabric Python LibFabric Python Lib
Fabric Python Lib
 
Gearman and Perl
Gearman and PerlGearman and Perl
Gearman and Perl
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Big Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your BrowserBig Data Scala by the Bay: Interactive Spark in your Browser
Big Data Scala by the Bay: Interactive Spark in your Browser
 
Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run them
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
 
オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
GPerf Using Jesque
GPerf Using JesqueGPerf Using Jesque
GPerf Using Jesque
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Celery with python
Celery with pythonCelery with python
Celery with python
 
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job Queue
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job QueueTask Scheduling and Asynchronous Processing Evolved. Zend Server Job Queue
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job Queue
 
Django Celery
Django Celery Django Celery
Django Celery
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 

More from Magento Dev

Yurii Hryhoriev "Php storm tips&tricks"
Yurii Hryhoriev "Php storm tips&tricks"Yurii Hryhoriev "Php storm tips&tricks"
Yurii Hryhoriev "Php storm tips&tricks"Magento Dev
 
DevHub 3 - Composer plus Magento
DevHub 3 - Composer plus MagentoDevHub 3 - Composer plus Magento
DevHub 3 - Composer plus MagentoMagento Dev
 
DevHub 3 - Pricing
DevHub 3 - PricingDevHub 3 - Pricing
DevHub 3 - PricingMagento Dev
 
Magento2 airplane
Magento2 airplaneMagento2 airplane
Magento2 airplaneMagento Dev
 
Imagine recap-devhub
Imagine recap-devhubImagine recap-devhub
Imagine recap-devhubMagento Dev
 
Разработка на стероидах или как я перестал бояться и полюбил свою IDE
Разработка на стероидах или как я перестал бояться и полюбил свою IDEРазработка на стероидах или как я перестал бояться и полюбил свою IDE
Разработка на стероидах или как я перестал бояться и полюбил свою IDEMagento Dev
 
Top 5 magento secure coding best practices Alex Zarichnyi
Top 5 magento secure coding best practices   Alex ZarichnyiTop 5 magento secure coding best practices   Alex Zarichnyi
Top 5 magento secure coding best practices Alex ZarichnyiMagento Dev
 
Magento 2 Page Cache
Magento 2 Page CacheMagento 2 Page Cache
Magento 2 Page CacheMagento Dev
 
Data migration into eav model
Data migration into eav modelData migration into eav model
Data migration into eav modelMagento Dev
 
Choreography of web-services
Choreography of web-servicesChoreography of web-services
Choreography of web-servicesMagento Dev
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from JqueryMagento Dev
 

More from Magento Dev (17)

Yurii Hryhoriev "Php storm tips&tricks"
Yurii Hryhoriev "Php storm tips&tricks"Yurii Hryhoriev "Php storm tips&tricks"
Yurii Hryhoriev "Php storm tips&tricks"
 
DevHub 3 - Composer plus Magento
DevHub 3 - Composer plus MagentoDevHub 3 - Composer plus Magento
DevHub 3 - Composer plus Magento
 
DevHub 3 - Pricing
DevHub 3 - PricingDevHub 3 - Pricing
DevHub 3 - Pricing
 
DevHub 3 - CVS
DevHub 3 - CVSDevHub 3 - CVS
DevHub 3 - CVS
 
Magento2 airplane
Magento2 airplaneMagento2 airplane
Magento2 airplane
 
Imagine recap-devhub
Imagine recap-devhubImagine recap-devhub
Imagine recap-devhub
 
Разработка на стероидах или как я перестал бояться и полюбил свою IDE
Разработка на стероидах или как я перестал бояться и полюбил свою IDEРазработка на стероидах или как я перестал бояться и полюбил свою IDE
Разработка на стероидах или как я перестал бояться и полюбил свою IDE
 
Top 5 magento secure coding best practices Alex Zarichnyi
Top 5 magento secure coding best practices   Alex ZarichnyiTop 5 magento secure coding best practices   Alex Zarichnyi
Top 5 magento secure coding best practices Alex Zarichnyi
 
Magento 2 Page Cache
Magento 2 Page CacheMagento 2 Page Cache
Magento 2 Page Cache
 
Data migration into eav model
Data migration into eav modelData migration into eav model
Data migration into eav model
 
Magento devhub
Magento devhubMagento devhub
Magento devhub
 
Php + erlang
Php + erlangPhp + erlang
Php + erlang
 
Tdd php
Tdd phpTdd php
Tdd php
 
Autotest
AutotestAutotest
Autotest
 
Choreography of web-services
Choreography of web-servicesChoreography of web-services
Choreography of web-services
 
Security in PHP
Security in PHPSecurity in PHP
Security in PHP
 
Take more from Jquery
Take more from JqueryTake more from Jquery
Take more from Jquery
 

Gearman jobqueue

  • 1. Gearman Job Queue. Раскрываем недокументированные возможности
  • 2. Синхронное выполнение задач Client Client Client Client Client Client Client Task
  • 4. Очереди к ограниченным ресурсам необходимы! ● Пред-расчет данных ● Операции импорта/экспорта данных ● Обработка логов системы ● Маркетинговый анализ базы данных ● Почтовые рассылки ● Map/Reduce ● и многое другое...
  • 5. Выполнение задачи в асинхронном режиме Client Job Server Worker add job job handle execute success
  • 6. Client Client Client Client Client Client Client Task manager Worker Worker Worker Worker Worker
  • 7. About project Gearman Gearman = Manager 2005: originally Perl implementation by Danga Interactive 2008: rewrite in C by Brian Aker Used in: Digg (45+ servers, 400K jobs/day) Yahoo (60+ servers, 6M jobs/day) Xing.com Grooveshark ...
  • 8. Преимущества и недостатки ● Высокая скорость ● Мониторинг, администрирование ● Масштабируемость ● Слабая документация ● Балансировка нагрузки ● Работа с памятью ● Параллельное и асинхронное ● Отличия API в различных версиях выполнение задач ● Защита от потери очереди ● Multi-language API
  • 9. Gearman server monitoring Administrative Protocol > telnet localhost 4730 > Trying ::1... > Connected to localhost. > Escape character is '^]'. > wokers FD IP-ADDRESS CLIENT-ID : FUNCTION > status FUNCTION TOTAL RUNNING AVAILABLE_WORKERS GearUp: Gearman based monitoring service https://launchpad.net/gearup Mod Gearman http://labs.consol.de/nagios/mod-gearman/
  • 10. Client Client Client Client Client Client Client API Client API Gearman Gearman Worker API Worker API Worker Worker Worker Worker Worker
  • 11. client.php <?php # create our object $client= new GearmanClient(); # add the default server $client->addServer(); $workload = array( 'email' => 'nobody@example.com' , 'subject' => 'the subject' , 'message' => 'the message' ); # send email $client->doBackground( "send_mail" , json_encode($workload)); if ($client->returnCode() != GEARMAN_SUCCESS) { echo "bad return coden" ; exit; } ?>
  • 12. worker.php <?php # create the worker $worker = new GearmanWorker(); # add the default job server (localhost) $worker->addServer(); # add the reverse function $worker->addFunction( "send_mail" , "sendMail" ); # start to worker listening for job submissions while ($worker->work()); function sendMail($job) { $arg = json_decode($job->workload(), true); mail($arg[ 'email'], $arg[ 'subject' ], $arg[ 'message' ]); echo "email has been sentn" ; } ?>
  • 13. Client Gearman Worker Task register tasks work() doBackground() run task execute success
  • 14. worker.php <?php #... function sendMail($job) { $arg = json_decode($job->workload(), true); # connect to remote service $mail = new Mail($arg['email'], $arg['subject'], $arg['message']); # send email if (!$mail->send()){ # it needs to be solved } else { echo "email has been sentn"; } } ?>
  • 15. Client Gearman Worker Task doBackground() run task execute failure ???
  • 16. worker.php <?php #... function sendMail($job) { #... # send email if (!$mail->send()){ sleep(20); $client= new GearmanClient(); $client->addServer(); $client->doBackground("send_mail", $job->workload()); echo "error has happened n"; } else { echo "email has been sentn"; } } ?>
  • 17. Client Gearman Worker Task doBackground() run task execute sleep(20) doBackground() failure run task execute sleep(20) doBackground() failure run task execute success
  • 18. worker.php <?php #... function sendMail($job) { #... # send email if (!$mail->send()){ setCron("send_mail", $job->workload(), 20); echo "error has happened n"; } else { echo "email has been sentn"; } } ?>
  • 19. Client Gearman Worker Task Cron doBackground() run task execute failure do postponed delay doBackground() run task execute do postponed failure delay doBackground() run task execute success do postponed
  • 20. Solution Credit: — In ver. 0.20 added when_to_run tasks functionality — But public API doesn't support that functionality — Neither does PECL Gearman module — Documentation also is silent about it John Ewart Software Engineer
  • 21. worker.php <?php #... function sendMail($job) { #... # send email if (!$mail->send()){ $client= new GearmanClient(); $client->addServer(); $time = time() + 20; $client->doSuspended("send_mail", $job->workload(), NULL, $time); echo "error has happened n" ; } else { echo "email has been sentn" ; } } ?>
  • 22. Suspended task execution Client Gearman Worker Task doBackground() run task execute doSuspended() failure delay run task execute doSuspended() failure delay run task execute success
  • 23. client.php <?php $client= new GearmanClient(); $client->addServer(); $workload = array('value' => 1, 'limit_attempts' => 3); $client->doBackground( "remote_procedure_call", json_encode($workload)); if ($client->returnCode() != GEARMAN_SUCCESS) { echo "bad return coden" ; exit; } ?>
  • 24. worker.php <?php #... $worker->addFunction( 'remote_procedure_call' , 'rpcJobHandler' ); while ($worker->work()); function rpcJobHandler($job) { $args = json_decode($job->workload(), true); try { // Execute task remoteProcedureCall($args[ 'value']); } catch (Exception $e) { echo "Failure, reason: " . $e->getMessage() . "n"; } } function remoteProcedureCall(&$value) { // Accept value only less than 3 if ($value < 3) { $value++; throw new Exception ("Service is unavailable" ); } } ?>
  • 25. worker.php — break of task loop <?php #... function rpcJobHandler($job) { $args = json_decode($job->workload(), true); try { remoteProcedureCall($args[ 'value']); } catch (Exception $e) { if (!isset($args['attempt' ])) $args[ 'attempt' ] = 0; if (empty($args['limit_attempts' ]) or $args['attempt' ] <= $args[ 'limit_attempts' ]) { $client = new GearmanClient(); $client->addServer(); if (method_exists($client, 'doSuspended' )) { $time = getExecutionTime($args['attempt' ]); $args[ 'attempt' ]++; $client->doSuspended('run', json_encode($args), null, $time); } } else { echo "Failure, reason: " . $e->getMessage() . "n"; } } } ?>
  • 26. Geometric progression <?php #... function getExecutionTime($attempt) { return time() + pow(2, (int)$attempt) * 10; } ?> attempt seconds delta time 0 10 10s 1 20 20s 2 40 40s 3 80 1m 20s 4 160 2m 40s 5 320 5m 20s 6 640 10m 40s 7 1280 21m 20s 8 2560 42m 40s 9 5120 1h 25m 20s 10 10240 2h 50m 40s
  • 27. Q &A