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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Tymon Tobolski
July 01, 2015
Programming
200
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Sidekiq
Tymon Tobolski
July 01, 2015
More Decks by Tymon Tobolski
See All by Tymon Tobolski
Only possible with Elixir - ubots Case Study
teamon
0
300
Fun with Elixir Macros
teamon
1
590
Elixir GenStage & Flow
teamon
2
1.1k
Elixir - Bydgoszcz Web Development Meetup
teamon
2
990
Git - Monterail style
teamon
1
210
Rails Assets wroc_love.rb
teamon
1
800
Angular replacements for jQuery-based libraries
teamon
1
420
Angular replacements for jQuery-based libraries
teamon
2
340
Rails Assets LRUG
teamon
0
7.6k
Other Decks in Programming
See All in Programming
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
180
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
200
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
540
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
13k
The NotImplementedError Problem in Ruby
koic
1
840
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
290
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
560
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Are puppies a ranking factor?
jonoalderson
1
3.6k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Mobile First: as difficult as doing things right
swwweet
225
10k
From π to Pie charts
rasagy
0
210
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Navigating Team Friction
lara
192
16k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
What's in a price? How to price your products and services
michaelherold
247
13k
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