Twoja aplikacja ma problemy z przekroczeniem czasu oczekiwania na wykonanie zapytania lub niektóre żądania, takie jak generowanie danych, zabierają zbyt dużo czasu? A może chcesz połączyć wykonywanie jobów z Sidekiq’a z częścią front-endową?
Piotr Jaworski. Ruby on Rails & JavaScipt Developer, z zamiłowania tworzy techniczne teksty dla krakowskiego software house Nopio. Obecnie pracuje w Londynie. Programowanie to nie tylko jego sposób na życie, ale przede wszystkim pasja. Uwielbia podróżować i aktywnie spędzać czas. Fan sportu, głównie siatkówki i futbolu.
Możesz na przykład powiadomić użytkownika, że dane, o które prosił, są gotowe do pobrania lub wyświetlenia. Spowoduje to wysłanie zwykłego powiadomienia, takiego jak na Facebooku, gdy ktoś doda Cię do znajomych lub napisze nową wiadomość. Jeśli odpowiedź brzmi „tak”, ten tutorial jest dla Ciebie!
Spis treści
Wstęp
W tym tutorialu omówię jak działają Sidekiq i Pusher, jak połączyć je na back-endzie i front-endzie oraz wyjaśnię korzyści z ich wspólnego wykorzystania. Zaczynajmy!
Myślę, że prawdopodobnie wiesz coś o Sidekiq lub nawet Pusher — jeśli nie, tutaj jest krótkie wprowadzenie dla ciebie.
Sidekiq to prosty procesor pracy w tle napisany w języku Ruby. Jest znacznie bardziej wydajny niż Resque lub DelayedJob. W jaki sposób działa? To narzędzie pozwala aplikacji na przetwarzanie kodu w tle w Ruby, bez konfliktów z przychodzącymi żądaniami do serwera. Możesz przetwarzać ogromne zapytania SQL, generować plik, przesyłać go później do S3 itd. — bez żadnych ograniczeń!
Pusher to narzędzie używane do budowania aplikacji działających w czasie rzeczywistym, używany do takich funkcjonalności, jak czat lub pasek postępu przesyłania plików. Możesz zaimplementować kod na back-endzie, przetworzyć go, a następnie wysłać wynik do front-endu za pomocą web-sockets. To właśnie robi Pusher!
Jak możemy je połączyć? To naprawdę proste, musimy wysłać / przesłać wynik przez websocket z naszego back-endu do konkretnego kanału i nazwy połączenia do front-endu. Zasadniczo front-end czeka na dane na konkretnym kanale i połączeniu. Po otrzymaniu danych robi coś z wynikiem — np. wyświetla go.
Przykłady wykorzystania? Czat, wideokonferencja, system powiadomień, transmisja danych na żywo lub jeszcze więcej! Wszystkie te funkcje można zbudować za pomocą Pushera. Świetne tutoriale na ten temat można znaleźć tutaj.
Wstęp do aplikacji
Skoro teraz wiesz więcej na temat obu narzędzi, porozmawiajmy o aplikacji, którą będziemy budować. Zrobimy prosty szkielet i połączymy Sidekiq i Pusher. Zasadniczo poradzimy sobie z ciężkim przetwarzaniem danych w Sidekiq i wyślemy wynik na front-end — w czasie rzeczywistym. Chcę tylko pokazać koncepcję aplikacji, opisując, jak możesz stworzyć coś większego i dostosowanego do Twoich potrzeb.
Stwórzmy nową aplikację:
1 2 |
Shell 1 $ rails new sidekiq_with_pusher |
Następnie zrobimy trochę porządków w Gemfile. Pozostawimy tylko potrzebne gemy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Ruby 1 source 'https://rubygems.org' 2 3 git_source(:github) do |repo_name| 4 repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") 5 "https://github.com/#{repo_name}.git" 6 end 7 8 gem 'rails', '~> 5.1.4' 9 gem 'sqlite3' 10 gem 'puma', '~> 3.7' 11 gem 'sass-rails', '~> 5.0' 12 gem 'uglifier', '>= 1.3.0' 13 gem 'redis', '~> 3.0' 14 15 group :development, :test do 16 gem 'pry-rails' 17 end 18 19 group :development do 20 gem 'listen', '>= 3.0.5', '< 3.2' 21 gem 'spring' 22 gem 'spring-watcher-listen', '~> 2.0.0' 23 end git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end gem 'rails', '~> 5.1.4' gem 'sqlite3' gem 'puma', '~> 3.7' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'redis', '~> 3.0' group :development, :test do gem 'pry-rails' end group :development do gem 'listen', '>= 3.0.5', '< 3.2' gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end |
Konfiguracja aplikacji
Dodajmy potrzebne gemy do Gemfile.
1 2 3 4 |
Ruby 1 gem 'sidekiq' 2 gem 'foreman' 3 gem 'jquery-rails' |
Jak zapewne wiesz, jQuery nie jest już dodane w Railsach, więc musimy dodać je ręcznie. Będziemy używać jego do robienia zapytań AJAXowych bez pisania zbyt dużej ilości kodu.
Dodaliśmy także Sidekiq i Foreman.
Czym jest Foreman? To gem, który zarządza plikami Procfile wykorzystywanych na Heroku, gdzie możemy zdefiniować jakie serwisy będą wykonywane w naszej aplikacji.
Jeśli nie masz zainstalowanego Redisa, zrób to proszę teraz. Będziemy potrzebować go do włączenia Sidekiqa — w innym przypadku nie będzie działał:
1 2 |
Shell 1 $ brew install redis |
Jeśli nie używasz systemu macOS, tutaj znajdziesz tutorial, który opisuje sposób instalacji Ubuntu.
Następnie dodaj Procfile, który uruchomi w jednej karcie terminala dwa procesy — redis-server i Sidekiq
1 2 3 |
Ruby 1 redis: redis-server /usr/local/etc/redis.conf 2 worker: bundle exec sidekiq |
Zainstalujmy wszystkie dodane gemy:
1 2 |
Shell 1 $ bundle install |
Teraz uruchomimy nasz Procfile:
1 2 |
Shell 1 $ foreman start -f Procfile |
Nasza aplikacja musi mieć jakiś kontroler i akcję, wygenerujemy więc HomeController. Stwórzmy także akcję index, która będzie zajmowała się renderowaniem plików oraz akcję generate, która będzie zbierała wszystkie potrzebne nam dane:
1 2 |
Shell 1 $ rails g controller Home index generate |
Następnie stwórzmy workera, który będzie wszystko razem spinał:
1 2 |
Shell 1 $ rails g sidekiq:worker Generator |
Zaktualizuj proszę ścieżki, by oznaczyć stronę główną i akcję generate:
1 2 3 4 5 6 |
Ruby 1 Rails.application.routes.draw do 2 root 'home#index' 3 get 'home/generate' 4 end 5 Sign up for free |
Nie potrzebujemy Turbolinków, więc usuńmy je z application.html.erb:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
XHTML 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>SidekiqWithPusher</title> 5 <%= csrf_meta_tags %> 6 7 <%= stylesheet_link_tag 'application', media: 'all' %> 8 <%= javascript_include_tag 'application' %> 9 </head> 10 11 <body> 12 <%= yield %> 13 </body> 14 </html> </body> </html> |
Usuń je z pliku application.js, a także dodaj bibliotekę jQuery:
1 2 3 4 5 |
JavaScript 1 //= require rails-ujs 2 //= require jquery 3 //= require jquery_ujs 4 //= require_tree . |
Teraz spróbuj zrestartować serwer, żeby sprawdzić czy wszystko zostało poprawnie skonfigurowane.
1 2 |
Shell 1 $ rails server |
Wejdź na stronę http://localhost:3000.