Cloud : Traitements asynchrones sur le Cloud avec Sidekiq
Au programme
Nous allons construire une application basique avec Sidekiq afin de lancer un scheduler nous permettant de réaliser une tache simple, à savoir : récupérer la date et l'heure actuelle toutes les minutes.
En local pour commencer
Vous pouvez récupérer le code ci-dessous sur GitHub au lien suivant :
Construction du squelette de l'application avec le lancement de Sidekiq
Dans ce tutoriel je vais utiliser VSCode en éditeur sur un environnement Linux Ubuntu (VM,WSL,multipass,serveur ou workstation)
- Créez votre répertoire projet et ouvrez le sur VSCode
- Création du fichier Gemfile et ajout des dépendances
source 'https://rubygems.org'
gem 'carioca', '~> 2.0'
gem 'sidekiq', '~> 6.4.1'
gem 'sidekiq-cron', '~> 1.2'
gem 'redis', '~>4.6'

- sidekiq : lancement de taches de fond
- sidekiq-cron : scheduler
- redis : stockage des jobs
- carioca : conteneur et registre avec inversion de contrôle pour vos applications
Voir :
- Création des dossiers config, helpers, workers, lib
- config : Contient la configuration de l'application
- helpers : Contient des méthodes utiles
- workers : Contient les workers à lancer par les différents jobs.
- Dans le dossier config créez un fichier init.rb
Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
def get_config
ApplicationController.configuration.settings
end
Sidekiq.configure_server do |config|
config.redis = { url: get_config.backend.redis.jobs.url.to_s }
end
Sidekiq.configure_client do |config|
config.redis = { url: get_config.backend.redis.jobs.url.to_s }
end

- Dans les dossiers helpers, workers et lib ajouter un fichier "init.rb" qui importera tous les fichiers du dossier
Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each { |file| require file unless File.basename(file) == 'init.rb' }

Création du fichier config.ru pour le lancement de l'application :
require 'sidekiq'
require 'sidekiq/web'
require 'sidekiq/cron/web'
require_relative 'runner'
require_relative 'config/init'
secret_key = SecureRandom.hex(32)
use Rack::Session::Cookie, secret: secret_key, same_site: true, max_age: 86400
run Sidekiq::Web
Ligne 2 et 3 : "sidekiq/web" et "sidekiq/cron/web" permettent de lancer l'interface web de sidekiq
- Ligne 8 et 9 : création d'une session
- Ligne 10 : lancement de l'application

- Création du fichier de configuration config/settings.yml :
:runner:
:default:
:backend:
:redis:
:jobs:
:url: redis://localhost:6379/1
:development:
:application:
:name: Tutoriel Sidekiq

Création du fichier runner.rb :
require 'sidekiq'require 'sidekiq-cron'
require 'carioca'
environment = ENV['RUBY_ENV'] ? ENV['RUBY_ENV'].to_sym : :development
Carioca::Registry.configure do |spec|
spec.debug = true
spec.init_from_file = false
spec.log_file = '/tmp/tutoriel.log'
spec.config_file = './config/settings.yml'
spec.config_root = :runner
spec.environment = environment
spec.default_locale = :fr
spec.log_level = :debug
spec.locales_load_path << Dir["#{File.expand_path('./config/locales')}/*.yml"]
spec.debugger_tracer = :logger
end
class ApplicationController < Carioca::Container
inject service: :configuration
end
require_relative 'helpers/init'
require_relative 'config/init'
require_relative 'workers/init'
Sidekiq::Cron::Job.destroy_all!
Sidekiq.logger.info "Initialisation : #{get_config.application.name}"
Sidekiq::Cron::Job.create(name: "Date",
cron: '* * * * *', class: "Tutoriel::Workers::Date")
Sidekiq.logger.info "Injection : job Date successfull"
Sidekiq.logger.info 'Runner initialized'


Ligne 1 à 3 : récupération des dépendances
- ligne 5 : récupération de l'environnement
- Ligne 7 à 18 : configuration de Carioca
- Ligne 20 à 22 : Injection du service de configuration de Carioca
- Ligne 24 à 26 : Import des fichiers
- Ligne 28 : Suppression des jobs Sidekiq au lancement
- Ligne 33 à 34 : Création du job Date avec un CRON de lancement toutes les minutes
Création du fichier de job, dans notre cas date.rb
module Tutoriel module Workers
class Date
include Sidekiq::Worker
sidekiq_options retry: false
def perform
end
end
end
end

Vous pouvez désormais lancer Sidekiq avec la commande :
sidekiq -r ./runner.rb
Vous pouvez désormais lancer l'interface web de Sidekiq grâce à la commande :
rackup
Création du job de récupération de la date
- Ajout d'une librairie Redis pour l'ajout de la date en base de données
- Création d'un dossier lib
- Ajout du fichier "lib/init.rb"
Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each { |file| require file unless File.basename(file) == 'init.rb' }
- Ajout de l'url redis de la base de données générale de l'application
:runner:
:default:
:backend:
:redis:
:jobs:
:url: redis://localhost:6379/1
:tutoriel:
:url: redis://localhost:6379/2
:development:
:application:
:name: Tutoriel Sidekiq
- Ajout du fichier lib/redis.rb
require 'redis'
module Backends
class RedisClient
include Singleton
attr_accessor :spool
def initialize
conf = { url: get_config.backend.redis.tutoriel.url }
@store = ::Redis.new conf
end
def list
@store.keys('*_*')
end
def get(entry:)
@store.get(entry)
end
def delete(entry:)
@store.del entry
end
def upsert(entry: , data:)
@store.set entry, data
end
alias update upsert
alias create upsert
def exist?(key:)
!@store.get(key).nil?
end
def flush
@store.flushdb
end
end
end
- Ajout du helper "helpers/backend.rb"
module Tutoriel module Helpers
module Backend
def get_redis
return Backends::RedisClient.instance
end
end
end
end

Définition du job à effectuer par le worker Date
require 'date'
module Tutoriel
module Workers
class Date
include Sidekiq::Worker
include Tutoriel::Helpers::Backend
sidekiq_options retry: false
def perform
date = DateTime.now
get_redis.upsert(entry: 'date', data: date)
end
end
end
end

👍 Vous pouvez désormais lancer sidekiq et votre job va s’exécuter en fonction du CRON que vous avez défini.
Visualiser la base de données Redis dans VSCode pour voir si le changement est bien effectué
- Allez sur l'onglet Extensions

- Saisissez "database client" dans la barre de recherche

- Sélectionnez le premier choix et installez l'extension
- Redémarrez VSCode si nécessaire
- Vous avez désormais deux nouveaux onglets sur votre barre latérale, allez sur l'onglet "NoSQL"

- Cliquez sur la base Redis, puis sur l'onglet "2" en fonction de ce que vous avez choisi comme URL dans le fichier de configuration de l'application

- vous visualisez le contenu de la base de données, vous avez une clé date définie, cliquez dessus pour obtenir sa valeur

- Vous visualisez le contenu

Découverte de l'interface web Sidekiq
Rendez-vous sur localhost:9292 après avoir lancé votre interface web avec la commande "rackup
".

Sur le dashboard vous pouvez visualiser toutes les queues ainsi que différentes informations à leur sujet.
Vous avez par exemple le nombre de jobs en échec, traités etc..
Vous pouvez également arrêter tous les processus ou uniquement certains.
Je vous invite à jouer avec l'exemple pour mieux découvrir la plateforme.