Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sidekiq

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 Sidekiq

Avatar for Tymon Tobolski

Tymon Tobolski

July 01, 2015
Tweet

More Decks by Tymon Tobolski

Other Decks in Programming

Transcript

  1. SYNCHRONOUS DELIVERY class CommentsController < ApplicationController def create @comment =

    @post.comments.create!(comment_params) # T = 10ms Notifications.notify_commenters(@comment) # T = 100.000ms, boom, timeout! head :ok end end class Notifications def self.notify_commenters(comment) comment.post.comments_authors.each do |user| send_email_about_new_comment(user, comment) # T += 1000ms end end end © Tymon Tobolski, 2015
  2. ASYNCHRONOUS DELIVERY class CommentsController < ApplicationController def create @comment =

    @post.comments.create!(comment_params) # T = 10ms NotifyCommentersWorker.perform_async(@comment.id) # T = 11ms, \o/ head :ok end end class Notifications def self.notify_commenters(comment) comment.post.comments_authors.each do |user| send_email_about_new_comment(user, comment) # T += 1000ms still, but we don't care anymore end end end © Tymon Tobolski, 2015
  3. SIDEKIQ WORKER # app/workers/notify_commenters_worker.rb class NotifyCommentersWorker include Sidekiq::Worker def perform(comment_id)

    comment = Comment.find(comment_id) Notifications.notify_commenters(comment) end end © Tymon Tobolski, 2015
  4. REDIS.IO Redis is an open source, BSD licensed, advanced key-value

    cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs, blah blah blah ... © Tymon Tobolski, 2015
  5. REDIS.IO Redis is an open source, BSD licensed, advanced key-value

    cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs, blah blah blah ... © Tymon Tobolski, 2015
  6. LIST IN REDIS WORLD ... is really a list and

    an array and a stack and a queue © Tymon Tobolski, 2015
  7. QUEUE FIFO - FIRST IN, FIRST OUT ACTION QUEUE STATUS

    --------------------------- [] PUSH 1 [1] PUSH 2 [2,1] PUSH 3 [3,2,1] POP [3,2] PUSH 4 [4,3,2] POP [4,3] POP [4] © Tymon Tobolski, 2015
  8. QUEUE FIFO - FIRST IN, FIRST OUT ACTION mylist CONTENT

    -------------------------------- (nil) LPUSH mylist 1 [1] LPUSH mylist 2 [2,1] LPUSH mylist 3 [3,2,1] RPOP mylist [3,2] LPUSH mylist 4 [4,3,2] RPOP mylist [4,3] RPOP mylist [4] © Tymon Tobolski, 2015
  9. ALWAYS USE IDS BAD: NotifyCommentersWorker.perform_async(@comment) GOOD: NotifyCommentersWorker.perform_async(@comment.id) Job arguments MUST

    be serializable to JSON def perform(comment_id) comment = Comment.find(comment_id) # ... end © Tymon Tobolski, 2015
  10. IDEMPOTENT AND TRANSACTIONAL JOBS Sidekiq will execute your job at

    least once. def perform(...) # ... User.where(id: id1).update_all(["balance = balance + ?", amount]) User.where(id: id2).update_all(["balance = balance - ?", amount]) # ... end © Tymon Tobolski, 2015
  11. IDEMPOTENT AND TRANSACTIONAL JOBS Sidekiq will execute your job at

    least once. def perform(...) # ... ActiveRecord.transation do User.where(id: id1).update_all(["balance = balance + ?", amount]) User.where(id: id2).update_all(["balance = balance - ?", amount]) end # ... end © Tymon Tobolski, 2015
  12. FOREMAN / HEROKU # Procfile web: bin/rails server -p $PORT

    worker: bin/sidekiq © Tymon Tobolski, 2015
  13. SIDEKIQ WEB # Gemfile gem 'sinatra', :require => nil #

    config/routes.rb require 'sidekiq/web' authenticate :user, lambda { |u| u.admin? } do mount Sidekiq::Web => '/sidekiq' end © Tymon Tobolski, 2015