Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Sidekiq
Search
Tymon Tobolski
July 01, 2015
Programming
1
140
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
220
Fun with Elixir Macros
teamon
1
430
Elixir GenStage & Flow
teamon
2
970
Elixir - Bydgoszcz Web Development Meetup
teamon
2
760
Git - Monterail style
teamon
1
160
Rails Assets wroc_love.rb
teamon
1
690
Angular replacements for jQuery-based libraries
teamon
1
310
Angular replacements for jQuery-based libraries
teamon
2
300
Rails Assets LRUG
teamon
0
7.4k
Other Decks in Programming
See All in Programming
AIコードエディタの基盤となるLLMのFlutter性能評価
alquist4121
0
180
アプリを起動せずにアプリを開発して品質と生産性を上げる
ishkawa
0
2.2k
AtCoder Heuristic First-step Vol.1 講義スライド(山登り法・焼きなまし法編)
takumi152
4
1k
アーキテクトと美学 / Architecture and Aesthetics
nrslib
12
3.2k
SideKiqでジョブが二重起動した事象を深堀りしました
t_hatachi
0
270
新卒から4年間、20年もののWebサービスと 向き合って学んだソフトウェア考古学
oguri
8
7k
Devinのメモリ活用の学びを自社サービスにどう組み込むか?
itarutomy
0
1.9k
Going Structural with Named Tuples
bishabosha
0
190
PHPUnit 高速化テクニック / PHPUnit Speedup Techniques
pinkumohikan
1
1.3k
ノーコードツールの裏側につきまとう「20分岐」との戦い
oguemon
0
110
パスキーのすべて / 20250324 iddance Lesson.5
kuralab
0
140
php-fpm がリクエスト処理する仕組みを追う / Tracing-How-php-fpm-Handles-Requests
shin1x1
5
890
Featured
See All Featured
RailsConf 2023
tenderlove
29
1k
YesSQL, Process and Tooling at Scale
rocio
172
14k
Practical Orchestrator
shlominoach
186
10k
How to train your dragon (web standard)
notwaldorf
91
5.9k
A designer walks into a library…
pauljervisheath
205
24k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.5k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
4
500
Fireside Chat
paigeccino
37
3.4k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Typedesign – Prime Four
hannesfritz
41
2.6k
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