Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passer de delayed_job à good_job #3338

Merged
merged 14 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ gem "pundit"
gem "devise_token_auth", github: "lynndylanhurley/devise_token_auth"

# Jobs
gem "delayed_job_active_record"
gem "delayed_job_web"
gem "delayed_cron_job"
gem "good_job"
gem "daemons"

# JSON serialization and queries
Expand Down
46 changes: 17 additions & 29 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ GEM
coderay (1.1.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.1.10)
concurrent-ruby (1.2.0)
crack (0.4.5)
rexml
crass (1.0.6)
Expand All @@ -163,18 +163,6 @@ GEM
database_cleaner-core (2.0.1)
date (3.3.3)
debug_inspector (1.1.0)
delayed_cron_job (0.9.0)
fugit (>= 1.5)
delayed_job (4.1.11)
activesupport (>= 3.0, < 8.0)
delayed_job_active_record (4.1.7)
activerecord (>= 3.0, < 8.0)
delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.4)
activerecord (> 3.0.0)
delayed_job (> 2.0.3)
rack-protection (>= 1.5.5)
sinatra (>= 1.4.4)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (4.8.1)
Expand Down Expand Up @@ -212,11 +200,19 @@ GEM
faraday (>= 1, < 3)
faraday-net_http (3.0.2)
ffi (1.15.5)
fugit (1.7.2)
fugit (1.8.1)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
globalid (1.0.1)
globalid (1.1.0)
activesupport (>= 5.0)
good_job (3.12.1)
activejob (>= 6.0.0)
activerecord (>= 6.0.0)
concurrent-ruby (>= 1.0.2)
fugit (>= 1.1)
railties (>= 6.0.0)
thor (>= 0.14.1)
webrick (>= 1.3)
groupdate (6.1.0)
activesupport (>= 5.2)
hashdiff (1.0.1)
Expand Down Expand Up @@ -296,8 +292,6 @@ GEM
activesupport (>= 5.2, < 7.1)
msgpack (1.6.0)
multi_xml (0.6.0)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
net-imap (0.3.4)
date
net-protocol
Expand All @@ -308,7 +302,7 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.0)
nokogiri (1.14.2)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
oauth2 (2.0.9)
Expand Down Expand Up @@ -421,7 +415,7 @@ GEM
activesupport (>= 4.2)
choice (~> 0.2.0)
ruby-graphviz (~> 1.2)
rails-html-sanitizer (1.4.4)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails_autolink (1.1.7)
rails (> 3.1)
Expand Down Expand Up @@ -532,11 +526,6 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
sinatra (3.0.4)
mustermann (~> 3.0)
rack (~> 2.2, >= 2.2.4)
rack-protection (= 3.0.4)
tilt (~> 2.0)
skylight (5.3.4)
activesupport (>= 5.2.0)
slim (4.1.0)
Expand Down Expand Up @@ -575,7 +564,7 @@ GEM
turbolinks-source (5.2.0)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.5)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.3.0)
uniform_notifier (1.16.0)
Expand Down Expand Up @@ -604,13 +593,14 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket (1.2.9)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.6)
zeitwerk (2.6.7)

PLATFORMS
ruby
Expand All @@ -636,16 +626,14 @@ DEPENDENCIES
chartkick (~> 3.4.0)
daemons
database_cleaner
delayed_cron_job
delayed_job_active_record
delayed_job_web
devise
devise-async
devise_invitable
devise_token_auth!
dotenv-rails
factory_bot
faker
good_job
groupdate (~> 6.1)
hiredis
icalendar (~> 2.5)
Expand Down
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
web: ./bin/start_web_server
jobs: bundle exec bin/delayed_job run
jobs: bundle exec bundle exec good_job start
postdeploy: bundle exec rake db:migrate
2 changes: 1 addition & 1 deletion Procfile.dev
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
web: ./bin/start_web_server
worker: ./bin/rake jobs:work
jobs: bundle exec bundle exec good_job start
francois-ferrandis marked this conversation as resolved.
Show resolved Hide resolved
js: yarn build --mode=development --watch --progress
3 changes: 3 additions & 0 deletions app/jobs/application_job.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# frozen_string_literal: true

class ApplicationJob < ActiveJob::Base
include DefaultJobBehaviour

queue_as :default
end
24 changes: 24 additions & 0 deletions app/jobs/concerns/default_job_behaviour.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module DefaultJobBehaviour
extend ActiveSupport::Concern

included do
# This retry_on means:
# "retry 20 times with an exponential backoff, then mark job as discarded"
#
# Exponential backoff is n^4, so wait times between retries will be as follows:
# attempt: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# backoff: 1s, 16s, 81s, 4m, 10m, 21m, 40m, 68m, 109m, 166m, 4h, 6h, 8h, 11h, 14h, 18h, 23h, 29h, 36h, 44h
retry_on(StandardError, wait: :exponentially_longer, attempts: 20)

# Makes sure every failed attempt is logged to Sentry
# (see: https://github.com/bensheldon/good_job#retries)
around_perform do |_job, block|
block.call
rescue StandardError => e
Sentry.capture_exception(e)
raise # will be caught by the retry mechanism
end
end
end
53 changes: 0 additions & 53 deletions app/jobs/cron_job.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,15 @@
# frozen_string_literal: true

class CronJob < ApplicationJob
# Cron jobs superclass
# See https://github.com/codez/delayed_cron_job#custom-cronjob-superclass
# It mostly ensures there is only one single scheduled job of each cron job class.
queue_as :cron

class_attribute :cron_expression

class << self
def schedule
set(cron: cron_expression).perform_later unless scheduled?
update_cron_expression!
end

def remove
delayed_job.destroy if scheduled?
end

def scheduled?
delayed_job.present?
end

def update_cron_expression!
delayed_job.update!(cron: cron_expression)
end

def delayed_job
Delayed::Job
.where("handler LIKE ?", "%job_class: #{name}%")
.first
end
end

## Actual Cron Jobs
#
class FileAttenteJob < CronJob
# Every 10 minutes, from 9:00 to 18:00
self.cron_expression = "0/10 9,10,11,12,13,14,15,16,17,18 * * *"

def perform
FileAttente.send_notifications
end
end

class ReminderJob < CronJob
# At 3:00 every day
self.cron_expression = "0 3 * * *"

def perform
Rdv.not_cancelled.day_after_tomorrow.find_each do |rdv|
run_at = rdv.starts_at - 48.hours
Expand All @@ -57,9 +19,6 @@ def perform
end

class UpdateExpirationsJob < CronJob
# At 1:00 every day
self.cron_expression = "0 1 * * *"

def perform
[PlageOuverture, Absence].each do |klass|
klass.not_expired.find_each(&:refresh_expired_cached)
Expand All @@ -68,9 +27,6 @@ def perform
end

class WarmUpOccurrencesCache < CronJob
# At 23:00 every day
self.cron_expression = "0 23 * * *"

def perform
[PlageOuverture, Absence].each do |klass|
klass.regulieres.not_expired.find_each do |model|
Expand All @@ -81,9 +37,6 @@ def perform
end

class DestroyOldRdvsJob < CronJob
# At 2:00 every day
self.cron_expression = "0 2 * * *"

def perform
Rdv.unscoped.where(starts_at: ..2.years.ago).each do |rdv|
rdv.skip_webhooks = true
Expand All @@ -93,9 +46,6 @@ def perform
end

class DestroyOldPlageOuvertureJob < CronJob
# At 01:00 every day
self.cron_expression = "0 1 * * *"

def perform
po_exceptionnelle_closed_since_1_year = PlageOuverture.where(recurrence: nil).where(first_day: ..1.year.ago)
po_reccurent_closed_since_1_year = PlageOuverture.where(recurrence_ends_at: ..1.year.ago)
Expand All @@ -107,9 +57,6 @@ def perform
end

class DestroyRedisWaitingRoomKeys < CronJob
# At 03:00 every day
self.cron_expression = "0 3 * * *"

def perform
Rdv.reset_user_in_waiting_room!
end
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/outlook/create_event_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Outlook
class CreateEventJob < ApplicationJob
queue_as :outlook_sync

def perform(agents_rdv)
outlook_event = Outlook::Event.new(agents_rdv: agents_rdv).create
agents_rdv.update(outlook_id: outlook_event["id"], skip_outlook_update: true)
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/outlook/destroy_event_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Outlook
class DestroyEventJob < ApplicationJob
queue_as :outlook_sync

def perform(outlook_id, agent)
outlook_event = Outlook::Event.new(outlook_id: outlook_id, agent: agent).destroy

Expand Down
2 changes: 2 additions & 0 deletions app/jobs/outlook/mass_create_event_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Outlook
class MassCreateEventJob < ApplicationJob
queue_as :outlook_sync

def perform(agent)
agent.agents_rdvs.future.each(&:sync_create_in_outlook_asynchronously)
end
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/outlook/mass_destroy_event_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Outlook
class MassDestroyEventJob < ApplicationJob
queue_as :outlook_sync

def perform(agent)
agent.agents_rdvs.exists_in_outlook.each do |agents_rdv|
Outlook::DestroyEventJob.perform_now(agents_rdv.outlook_id, agents_rdv.agent)
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/outlook/update_event_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Outlook
class UpdateEventJob < ApplicationJob
queue_as :outlook_sync

def perform(agents_rdv)
Outlook::Event.new(agents_rdv: agents_rdv).update
end
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/rdv_upcoming_reminder_job.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class RdvUpcomingReminderJob < ApplicationJob
queue_as :reminders

def perform(rdv)
Notifiers::RdvUpcomingReminder.perform_with(rdv, nil)
end
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/sms_job.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class SmsJob < ApplicationJob
queue_as :sms

class InvalidMobilePhoneNumberError < StandardError; end

def perform(sender_name:, phone_number:, content:, provider:, api_key:, receipt_params:) # rubocop:disable Metrics/ParameterLists
Expand Down
6 changes: 5 additions & 1 deletion app/jobs/webhook_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class WebhookJob < ApplicationJob

queue_as :webhook

retry_on(OutgoingWebhookError, wait: :exponentially_longer, attempts: 10, queue: :webhook_retries) do |_job, error|
Sentry.capture_exception(error)
end

def perform(payload, webhook_endpoint_id)
webhook_endpoint = WebhookEndpoint.find(webhook_endpoint_id)

Expand Down Expand Up @@ -41,7 +45,7 @@ def perform(payload, webhook_endpoint_id)
# c'est en général lié à une mise à jour
# ou une suppression qui ne fonctionne pas
#
# Ce petit paliatif est là en attendant qu'ils
# Ce petit palliatif est là en attendant qu'ils
# fassent évoluer leur système.
def self.false_negative_from_drome?(body)
body = JSON.parse(body)
Expand Down
2 changes: 2 additions & 0 deletions app/mailers/custom_mailer_delivery_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# See https://www.bigbinary.com/blog/rails-5-2-allows-mailers-to-use-custom-active-job-class
class CustomMailerDeliveryJob < ActionMailer::MailDeliveryJob
include DefaultJobBehaviour

# Only discard DeserializationError if it is caused by a ActiveRecord::RecordNotFound.
# We don't want to discard a job when deserialization failed because of a DB failure for example.
rescue_from ActiveJob::DeserializationError do |exception|
Expand Down
4 changes: 2 additions & 2 deletions app/services/notifiers/rdv_upcoming_reminder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ def rdvs_users_to_notify
end

def notify_user_by_mail(user)
user_mailer(user).rdv_upcoming_reminder.deliver_later(queue: :mailers_low)
user_mailer(user).rdv_upcoming_reminder.deliver_later(queue: :mailers_low, priority: -10)
end

def notify_user_by_sms(user)
Users::RdvSms.rdv_upcoming_reminder(@rdv, user, @rdv_users_tokens_by_user_id[user.id]).deliver_later(queue: :sms_low)
Users::RdvSms.rdv_upcoming_reminder(@rdv, user, @rdv_users_tokens_by_user_id[user.id]).deliver_later(queue: :sms_low, priority: -10)
end
end
Loading