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
Background jobs with realtime results – RailsCl...
Search
Sergey Nartimov
September 15, 2012
Programming
5
210
Background jobs with realtime results – RailsClub'Moscow 2012
Sergey Nartimov
September 15, 2012
Tweet
Share
More Decks by Sergey Nartimov
See All by Sergey Nartimov
PubSub at Rails
lest
0
120
Rails in production - RubyConfBY 22 Mar 2015
lest
1
150
Sequel - BRUG 21 Feb 2015
lest
0
82
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
660
Authentication Security – RUBYSPB
lest
2
170
Geospatial applications on Rails
lest
8
410
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
650
Ruby Stdlib – Minsk.rb October 2012
lest
10
360
Other Decks in Programming
See All in Programming
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
440
Zendeskのチケットを Amazon Bedrockで 解析した
ryokosuge
3
310
アプリの "かわいい" を支えるアニメーションツールRiveについて
uetyo
0
270
機能追加とリーダー業務の類似性
rinchoku
2
1.3k
Ruby Parser progress report 2025
yui_knk
1
440
AIコーディングAgentとの向き合い方
eycjur
0
270
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
370
CloudflareのChat Agent Starter Kitで簡単!AIチャットボット構築
syumai
2
500
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
450
私の後悔をAWS DMSで解決した話
hiramax
4
210
Improving my own Ruby thereafter
sisshiki1969
1
160
基礎から学ぶ大画面対応(Learning Large-Screen Support from the Ground Up)
tomoya0x00
0
1.3k
Featured
See All Featured
Into the Great Unknown - MozCon
thekraken
40
2k
Git: the NoSQL Database
bkeepers
PRO
431
66k
A designer walks into a library…
pauljervisheath
207
24k
A Tale of Four Properties
chriscoyier
160
23k
Documentation Writing (for coders)
carmenintech
74
5k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.4k
The Pragmatic Product Professional
lauravandoore
36
6.9k
RailsConf 2023
tenderlove
30
1.2k
How to train your dragon (web standard)
notwaldorf
96
6.2k
The Power of CSS Pseudo Elements
geoffreycrofte
77
6k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Facilitating Awesome Meetings
lara
55
6.5k
Transcript
Фоновые задания с результатами в реальном времени Сергей Нартымов Brainspec
https://github.com/lest twitter: @just_lest
О себе • Rails, Rubinius, Elixir contributor • Señor software
engineer at Brainspec • Консалтинг, обучение, разработка Сергей Нартымов Brainspec https://github.com/lest twitter: @just_lest
Длительные операции • Отправка персонализированнх нотификаций • Обработка загружаемых файлов
• Генерация больших отчетов • Взаимодействие с медленным API
Принцип работы Браузер Приложение
Принцип работы Браузер Очередь заданий Приложение
Принцип работы Браузер Очередь заданий Рабочие процессы Приложение
Преимущества • Отзывчивость интерфейса • Распределение нагрузки
DelayedJob • https://github.com/collectiveidea/delayed_job • Выделен из Shopify • Задания хранятся
в базе данных • Сериализация с помощью YAML
DelayedJob class Device def deliver # long running method end
handle_asynchronously :deliver end
DelayedJob class Device def deliver # long running method end
handle_asynchronously :deliver end device = Device.new device.deliver
DelayedJob class LongTasks def send_mailer # Some other code end
handle_asynchronously :send_mailer, :priority => 20 def in_the_future # Some other code end # 5.minutes.from_now will be evaluated when in_the_future is called handle_asynchronously :in_the_future, :run_at => Proc.new { 5.minutes.from_now } end
DelayedJob object.delay(:queue => 'tracking').method Delayed::Job.enqueue job, :queue => 'tracking' handle_asynchronously
:tweet_later, :queue => 'tweets'
DelayedJob bundle exec rake jobs:work QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake
jobs:work
None
DelayedJob
Resque • https://github.com/defunkt/resque • Разработан и используется в Github •
Задания хранятся в Redis • Для сериализации используется JSON
Resque class Archive @queue = :file_serve def self.perform(repo_id, branch =
'master') repo = Repository.find(repo_id) repo.create_archive(branch) end end
Resque class Repository def async_create_archive(branch) Resque.enqueue(Archive, self.id, branch) end end
Resque QUEUE=file_serve rake resque:work QUEUES=critical,archive,high,low rake resque:work VERBOSE=1 QUEUE=* rake
resque:work
None
Resque plugins • resque-scheduler • resque-retry • resque-throttle • resque-workers-lock
• ...
Sidekiq • https://github.com/mperham/sidekiq • Выполняет задания в потоках • Используется
Celluloid • Задания хранятся в Redis • Сериализует данные в JSON
Sidekiq # app/workers/hard_worker.rb class HardWorker include Sidekiq::Worker def perform(name, count)
puts 'Doing hard work' end end
Sidekiq # app/workers/hard_worker.rb class HardWorker include Sidekiq::Worker def perform(name, count)
puts 'Doing hard work' end end HardWorker.perform_async('bob', 5)
Sidekiq class ImportantWorker include Sidekiq::Worker sidekiq_options :queue => :critical def
perform(*important_args) puts "Doing critical work" end end
Sidekiq bundle exec sidekiq
Sidekiq bundle exec sidekiq -c 100
Sidekiq bundle exec sidekiq bundle exec sidekiq \ -q critical,2
-q default
Sidekiq • Повторное выполнение в случае ошибок • Выполнение заданий
по расписанию • Совместимость с Resque
None
Что использовать?
Что использовать? • DelayedJob • Resque • Sidekiq
Общие советы • Храните в очереди идентификаторы, а не состояние
• Используйте after_commit в ActiveRecord для добавления задания в очередь • Избегайте блокировок
Rails 4 Queue Rails.queue.push SomeJob.new Rails.queue[:mail_queue].push MailJob.new
Результаты фоновых заданий
Результаты фоновых заданий • Обновить страницу вручную
Результаты фоновых заданий • Обновить страницу вручную • Автоматичекое обновление
через AJAX
Результаты фоновых заданий • Обновить страницу вручную • Автоматичекое обновление
через AJAX • Push результатов в браузер – WebSockets, long polling, ...
Push данных Очередь заданий Рабочие процессы Приложение Браузер
Push данных Очередь заданий Рабочие процессы Приложение Браузер Push сервер
Push данных Очередь заданий Рабочие процессы Приложение Браузер Push сервер
Push данных Очередь заданий Рабочие процессы Приложение Браузер Push сервер
Pusher • http://pusher.com/ • Сервис • Есть бесплатный тариф
Pusher
Pusher Pusher['my-channel'].trigger('my-event', {'message' => 'hello world'})
Pusher <script src="http://js.pusher.com/1.12/pusher.min.js"></script> var channel = pusher.subscribe('my-channel'); channel.bind('my-event', function(data) {
alert('Received my-event with message: ' + data.message); }); Pusher['my-channel'].trigger('my-event', {'message' => 'hello world'})
Faye • http://faye.jcoglan.com/
Faye • http://faye.jcoglan.com/ • Open source
Faye • http://faye.jcoglan.com/ • Open source • Серверная часть на
любой вкус – Ruby/EventMachine и Node.JS
Faye • http://faye.jcoglan.com/ • Open source • Серверная часть на
любой вкус – Ruby/EventMachine и Node.JS • Можно масштабировать
Faye • http://faye.jcoglan.com/ • Open source • Серверная часть на
любой вкус – Ruby/EventMachine и Node.JS • Можно масштабировать • Более тесная итеграция с приложением
Faye require 'faye' faye = Faye::RackAdapter.new(:mount => '/faye') faye.listen(9292)
Faye require 'faye' faye = Faye::RackAdapter.new(:mount => '/faye') faye.listen(9292) var
Faye = require('faye'), server = new Faye.NodeAdapter({mount: '/'}); server.listen(9292);
Faye <script src="http://localhost:9292/faye"></script> var client = new Faye.Client('http://localhost:9292/faye'); client.subscribe('/messages', function(message)
{ alert('Got a message: ' + message.text); });
Faye client = Faye::Client.new('http://localhost:9292/faye') client.publish('/messages', 'text' => 'Hello world')
None
Масштабирование Faye
Faye & Rails • Private Pub https://github.com/ryanb/private_pub • d'Anthès https://github.com/phenomena/danthes
Faye, Pusher, etc. • Уведомления • Обновление комментариев • Совместное
редактирование
Спасибо Сергей Нартымов Brainspec https://github.com/lest twitter: @just_lest