SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
Why Task Queues in
Python, Ruby and More!
      ~ a talk by Bryan Helmig
task queue noun ˈtask ˈkyü
a system for parallel execution of discrete
tasks in a non-blocking fashion.
               celery, resque, or home-grown...
broker noun broh-ker
the middle man holding the tasks
(messages) themselves.
               rabbitmq, gearman, redis, etc...
producer noun pruh-doo-ser
the code that places the tasks to be
executed later in the broker.
                        your application code!
consumer noun kuhn-soo-mer
also called the worker, takes tasks from
the broker and perform them.
           usually a daemon under supervision.
imagine this...
your app: posting a new message triggers
“new message” emails to all your friends.
def new_message(request):
    user = get_user_or_404(request)
    message = request.POST.get('message', None)

    if not message:
        raise Http404

    user.save_new_message(message)

    for friend in user.friends.all():
        friend.send_email(message)

    return redirect(reverse('dashboard'))
def new_message(request):
    user = get_user_or_404(request)
    message = request.POST.get('message', None)

    if not message:
        raise Http404

    user.save_new_message(message)

   for friend in user.friends.all():
       friend.send_email(message)

    return redirect(reverse('dashboard'))
the problem:
that works good for like 0-6 friends... but
what if you have 100,000? or more? will
your user ever get a response?
bad idea #1: ignore
make your users wait through your long
request/response cycle.
            your users are important, right?
bad idea #2: ajax
return the page fast with JS code that calls
another script in the browser’s background.
     duplicate calls & http cycles are not cool.
bad idea #3: cronjob
make a email_friends table with user_id &
message column. cron every 5/10 minutes.
                  backlogs will destroy you.
good idea: queues
the task to potentially email thousands of
users is put into a queue to be dealt with
later, leaving you to return the response.
@task
def alert_friends(user_id, message):
    user = User.objects.get(id=user_id)

    for friend in user.friends.all():
        friend.send_email(message)

def new_message(request):
    user = get_user_or_404(request)
    message = request.POST.get('message', None)
    if not message:
        raise Http404
    user.save_new_message(message)

    alert_friends.delay(user.id, message)

    return redirect(reverse('dashboard'))
RULE #1:
  adding a task to a queue should be
faster than performing the task itself.
RULE #2:
you should consume tasks faster than you
 produce them. if not, add more workers.
queue libraries:
1. celery (python) earlier...
2. resque (ruby) up next...
3. build your own grand finalé!
class MessageSend
  def self.perform(user_id, message)
    user = User.find(user_id)
    user.friends.each do |friend|
      friend.send_email(message)
    end
  end
end

class MessageController < ActionController::Base
  def new_message
    render(file: 'public/404.html',
           status: 404) unless params[:message]
    current_user.save_new_message(params[:message])

    Resque.enqueue(MessageSend,
        current_user.id, params[:message])

    redirect_to dashboard_url
  end
end
let’s build our own!
and let’s do it with redis, in php and
   in less than 50 lines of code!
     (not including the task code)
quick redis aside:
so, redis is a key-value store. values can
be strings, blobs, lists or hashes. we’ll use
lists and RPUSH and LPOP.
step #1: task runner
i’m envisioning this as a Task class with
various methods named after each task.
each method accepts an array $params.
class Tasks {
    public function email_friends($params) {
        $user_id = $params->user_id;
        $message = $params->message;

        # get $friends from a db query...
        $friends = array('paul@example.com',
                         'john@example.com');

        foreach ($friends as $friend) {
            echo "Fake email ".$friend.
                 " with ".$message."n";
        }
    }
}
step #2: worker
i think an infinite loop with a blocking
redis BLPOP will work. then it needs to run
the right method on the Task object.
include_once 'redis.php'; # sets up $redis, $queue
include_once 'tasks.php';

$tasks = new Tasks();

while (true) {
    # BLPOP will block until it gets an item..
    $data = $redis->blpop($queue, 0);
    $obj = json_decode($data[1]); # grab json...

    $method = $obj->task_name;
    $params = $obj->params;

    # calls the task: Task->$task_name($params)...
    call_user_func(array($tasks, $method), $params);
}
step #3: run it!
we will need to run the worker:

   ➜ php worker.php
step #4: producer
let’s make a handy add_task function for
easy placement of tasks into the queue.
include_once 'redis.php'; # sets up $redis & $queue

function add_task($task_name, $params) {
    global $redis, $queue;
    $data = Array('task_name' => $task_name,
                  'params'     => $params);
    $json = json_encode($data)
    $redis->rpush($queue, $json);
}

# an example of our task api...
add_task('email_friends',
   array('user_id' => 1234,
         'message' => 'I just bought a car!')
);
step #5: watch it
a command line that runs a worker is
standard. use something like supervisord
or god to run it & monitor it.
things missing:
our php example does not: store return
results, handle errors, route tasks,
degrade gracefully, log activity, etc...
the end
question time!

Contenu connexe

Tendances

Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
Celery: The Distributed Task Queue
Celery: The Distributed Task QueueCelery: The Distributed Task Queue
Celery: The Distributed Task QueueRichard Leland
 
Querying XML: XPath and XQuery
Querying XML: XPath and XQueryQuerying XML: XPath and XQuery
Querying XML: XPath and XQueryKatrien Verbert
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기경원 이
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱PgDay.Seoul
 
MySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKMySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKYoungHeon (Roy) Kim
 
PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language Weaveworks
 

Tendances (20)

Celery with python
Celery with pythonCelery with python
Celery with python
 
Introduction to Celery
Introduction to CeleryIntroduction to Celery
Introduction to Celery
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Celery: The Distributed Task Queue
Celery: The Distributed Task QueueCelery: The Distributed Task Queue
Celery: The Distributed Task Queue
 
Celery
CeleryCelery
Celery
 
Querying XML: XPath and XQuery
Querying XML: XPath and XQueryQuerying XML: XPath and XQuery
Querying XML: XPath and XQuery
 
Javascript Exercises
Javascript ExercisesJavascript Exercises
Javascript Exercises
 
Django Celery
Django Celery Django Celery
Django Celery
 
Expressjs
ExpressjsExpressjs
Expressjs
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
PHP POWERPOINT SLIDES
PHP POWERPOINT SLIDESPHP POWERPOINT SLIDES
PHP POWERPOINT SLIDES
 
Redis
RedisRedis
Redis
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
 
MySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELKMySQL Slow Query log Monitoring using Beats & ELK
MySQL Slow Query log Monitoring using Beats & ELK
 
React hooks
React hooksReact hooks
React hooks
 
PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language PromQL Deep Dive - The Prometheus Query Language
PromQL Deep Dive - The Prometheus Query Language
 
Flower and celery
Flower and celeryFlower and celery
Flower and celery
 
4.2 PHP Function
4.2 PHP Function4.2 PHP Function
4.2 PHP Function
 
Express JS
Express JSExpress JS
Express JS
 
Node.js Express Framework
Node.js Express FrameworkNode.js Express Framework
Node.js Express Framework
 

Similaire à Why Task Queues - ComoRichWeb

Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To BatchLuca Mearelli
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHPRohan Sharma
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Pedro Cunha
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful CodeGreggPollack
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Andre Foeken
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101Samantha Geitz
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
12-OO-PHP.pptx
12-OO-PHP.pptx12-OO-PHP.pptx
12-OO-PHP.pptxrani marri
 

Similaire à Why Task Queues - ComoRichWeb (20)

Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To Batch
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Oops in php
Oops in phpOops in php
Oops in php
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 
Introduction Php
Introduction PhpIntroduction Php
Introduction Php
 
Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11Ruby on Rails at PROMPT ISEL '11
Ruby on Rails at PROMPT ISEL '11
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)Rails workshop for Java people (September 2015)
Rails workshop for Java people (September 2015)
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
lab4_php
lab4_phplab4_php
lab4_php
 
lab4_php
lab4_phplab4_php
lab4_php
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Lecture9_OOPHP_SPring2023.pptx
Lecture9_OOPHP_SPring2023.pptxLecture9_OOPHP_SPring2023.pptx
Lecture9_OOPHP_SPring2023.pptx
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
12-OO-PHP.pptx
12-OO-PHP.pptx12-OO-PHP.pptx
12-OO-PHP.pptx
 

Dernier

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 

Dernier (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 

Why Task Queues - ComoRichWeb

  • 1. Why Task Queues in Python, Ruby and More! ~ a talk by Bryan Helmig
  • 2. task queue noun ˈtask ˈkyü a system for parallel execution of discrete tasks in a non-blocking fashion. celery, resque, or home-grown...
  • 3. broker noun broh-ker the middle man holding the tasks (messages) themselves. rabbitmq, gearman, redis, etc...
  • 4. producer noun pruh-doo-ser the code that places the tasks to be executed later in the broker. your application code!
  • 5. consumer noun kuhn-soo-mer also called the worker, takes tasks from the broker and perform them. usually a daemon under supervision.
  • 6. imagine this... your app: posting a new message triggers “new message” emails to all your friends.
  • 7. def new_message(request): user = get_user_or_404(request) message = request.POST.get('message', None) if not message: raise Http404 user.save_new_message(message) for friend in user.friends.all(): friend.send_email(message) return redirect(reverse('dashboard'))
  • 8. def new_message(request): user = get_user_or_404(request) message = request.POST.get('message', None) if not message: raise Http404 user.save_new_message(message) for friend in user.friends.all(): friend.send_email(message) return redirect(reverse('dashboard'))
  • 9. the problem: that works good for like 0-6 friends... but what if you have 100,000? or more? will your user ever get a response?
  • 10. bad idea #1: ignore make your users wait through your long request/response cycle. your users are important, right?
  • 11. bad idea #2: ajax return the page fast with JS code that calls another script in the browser’s background. duplicate calls & http cycles are not cool.
  • 12. bad idea #3: cronjob make a email_friends table with user_id & message column. cron every 5/10 minutes. backlogs will destroy you.
  • 13. good idea: queues the task to potentially email thousands of users is put into a queue to be dealt with later, leaving you to return the response.
  • 14. @task def alert_friends(user_id, message): user = User.objects.get(id=user_id) for friend in user.friends.all(): friend.send_email(message) def new_message(request): user = get_user_or_404(request) message = request.POST.get('message', None) if not message: raise Http404 user.save_new_message(message) alert_friends.delay(user.id, message) return redirect(reverse('dashboard'))
  • 15. RULE #1: adding a task to a queue should be faster than performing the task itself.
  • 16. RULE #2: you should consume tasks faster than you produce them. if not, add more workers.
  • 17. queue libraries: 1. celery (python) earlier... 2. resque (ruby) up next... 3. build your own grand finalé!
  • 18. class MessageSend def self.perform(user_id, message) user = User.find(user_id) user.friends.each do |friend| friend.send_email(message) end end end class MessageController < ActionController::Base def new_message render(file: 'public/404.html', status: 404) unless params[:message] current_user.save_new_message(params[:message]) Resque.enqueue(MessageSend, current_user.id, params[:message]) redirect_to dashboard_url end end
  • 19. let’s build our own! and let’s do it with redis, in php and in less than 50 lines of code! (not including the task code)
  • 20. quick redis aside: so, redis is a key-value store. values can be strings, blobs, lists or hashes. we’ll use lists and RPUSH and LPOP.
  • 21. step #1: task runner i’m envisioning this as a Task class with various methods named after each task. each method accepts an array $params.
  • 22. class Tasks { public function email_friends($params) { $user_id = $params->user_id; $message = $params->message; # get $friends from a db query... $friends = array('paul@example.com', 'john@example.com'); foreach ($friends as $friend) { echo "Fake email ".$friend. " with ".$message."n"; } } }
  • 23. step #2: worker i think an infinite loop with a blocking redis BLPOP will work. then it needs to run the right method on the Task object.
  • 24. include_once 'redis.php'; # sets up $redis, $queue include_once 'tasks.php'; $tasks = new Tasks(); while (true) { # BLPOP will block until it gets an item.. $data = $redis->blpop($queue, 0); $obj = json_decode($data[1]); # grab json... $method = $obj->task_name; $params = $obj->params; # calls the task: Task->$task_name($params)... call_user_func(array($tasks, $method), $params); }
  • 25. step #3: run it! we will need to run the worker: ➜ php worker.php
  • 26. step #4: producer let’s make a handy add_task function for easy placement of tasks into the queue.
  • 27. include_once 'redis.php'; # sets up $redis & $queue function add_task($task_name, $params) { global $redis, $queue; $data = Array('task_name' => $task_name, 'params' => $params); $json = json_encode($data) $redis->rpush($queue, $json); } # an example of our task api... add_task('email_friends', array('user_id' => 1234, 'message' => 'I just bought a car!') );
  • 28. step #5: watch it a command line that runs a worker is standard. use something like supervisord or god to run it & monitor it.
  • 29. things missing: our php example does not: store return results, handle errors, route tasks, degrade gracefully, log activity, etc...