Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Sidekiq
Tymon Tobolski
July 01, 2015
Programming
1
77
Sidekiq
Tymon Tobolski
July 01, 2015
Tweet
Share
More Decks by Tymon Tobolski
See All by Tymon Tobolski
Only possible with Elixir - ubots Case Study
teamon
0
100
Fun with Elixir Macros
teamon
1
320
Elixir GenStage & Flow
teamon
2
700
Elixir - Bydgoszcz Web Development Meetup
teamon
2
480
Git - Monterail style
teamon
1
70
Rails Assets wroc_love.rb
teamon
1
580
Angular replacements for jQuery-based libraries
teamon
1
220
Angular replacements for jQuery-based libraries
teamon
2
280
Rails Assets LRUG
teamon
0
6.9k
Other Decks in Programming
See All in Programming
React Nativeアプリを DDDで開発している話
nihemak
0
160
Swift Regex
usamik26
0
200
Get Ready for Jakarta EE 10
ivargrimstad
0
1.1k
社用PCのdotfiles管理 / dotfiles-in-company
yammerjp
0
140
エンジニアによる事業指標計測のススメ
doyaaaaaken
1
190
Scrum Fest Osaka 2022/5年で200人になったスタートアップの アジャイル開発の歴史とリアル
atamaplus
1
960
Running Laravel/PHP on AWS (AWS Builders Day Taiwan 2022)
dwchiang
0
170
Improving Developer Experience Through Tools and Techniques 2022
krzysztofzablocki
0
1.2k
チームでカレーを作ろう!アジャイルカレークッキング
akitotsukahara
0
880
#JJUG_CCC 「サポート」は製品開発? - JDBCライブラリ屋さんが実践する攻めのテクニカルサポートとJavaエンジニアのキャリアについて -
cdataj
0
430
IE Graduation Certificate
jxck
6
4.8k
VisualProgramming_GoogleHome_LINE
nearmugi
1
240
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
85
3.9k
The Straight Up "How To Draw Better" Workshop
denniskardys
225
120k
BBQ
matthewcrist
74
7.9k
The Illustrated Children's Guide to Kubernetes
chrisshort
15
36k
Thoughts on Productivity
jonyablonski
43
2.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
5
2.3k
Creatively Recalculating Your Daily Design Routine
revolveconf
207
10k
Robots, Beer and Maslow
schacon
152
7.1k
Statistics for Hackers
jakevdp
781
210k
Producing Creativity
orderedlist
PRO
334
37k
Done Done
chrislema
174
14k
Facilitating Awesome Meetings
lara
29
4k
Transcript
SIDEKIQ BACKGROUND JOBS IN RUBY © Tymon Tobolski, 2015
WHAT & WHY © Tymon Tobolski, 2015
class CommentsController < ApplicationController def create @comment = @post.comments.create!(comment_params) Notifications.notify_commenters(@comment)
head :ok end end © Tymon Tobolski, 2015
class Notifications def self.notify_commenters(comment) comment.post.comments_authors.each do |user| send_email_about_new_comment(user, comment) end
end end © Tymon Tobolski, 2015
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
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
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
MAGIC? © Tymon Tobolski, 2015
REDIS © Tymon Tobolski, 2015
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
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
LIST IN REDIS WORLD ... is really a list and
an array and a stack and a queue © Tymon Tobolski, 2015
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
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
FLOW © Tymon Tobolski, 2015
RULES Sidekiq Best Practices © Tymon Tobolski, 2015
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
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
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
CONCURRENCY & PARALLELISM def process(...) User.find_each do |user| send_email_to(user) end
end © Tymon Tobolski, 2015
CONCURRENCY & PARALLELISM def process(...) User.select(:id).find_each do |user| SendEmailWorker.perform_async(user.id) end
end © Tymon Tobolski, 2015
FOREMAN / HEROKU # Procfile web: bin/rails server -p $PORT
worker: bin/sidekiq © Tymon Tobolski, 2015
SIDEKIQ WEB © Tymon Tobolski, 2015
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
QUESTIONS? © Tymon Tobolski, 2015