From 7ee85e832e92bf6c25f0034b7a376243ddf45f3f Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 03:15:41 -0700 Subject: [PATCH 1/7] sidekiq configured --- Gemfile | 1 + Gemfile.lock | 7 +++++++ config/initializers/sidekiq.rb | 7 +++++++ config/sidekiq.yml | 4 ++++ docker-compose.yml | 13 +++++++++++++ test/test_helper.rb | 1 + 6 files changed, 33 insertions(+) create mode 100644 config/initializers/sidekiq.rb create mode 100644 config/sidekiq.yml diff --git a/Gemfile b/Gemfile index 3e518c4..d8790e5 100644 --- a/Gemfile +++ b/Gemfile @@ -68,3 +68,4 @@ gem 'webpacker-react', '~> 0.3.2' gem 'js-routes' gem 'rollbar' gem 'newrelic_rpm' +gem 'sidekiq' diff --git a/Gemfile.lock b/Gemfile.lock index 0775373..b0589be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,6 +94,7 @@ GEM activesupport childprocess (3.0.0) concurrent-ruby (1.1.7) + connection_pool (2.2.5) crass (1.0.6) docile (1.4.0) erubi (1.9.0) @@ -195,6 +196,7 @@ GEM rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) + redis (4.3.1) regexp_parser (1.8.2) responders (3.0.1) actionpack (>= 5.0) @@ -227,6 +229,10 @@ GEM selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) + sidekiq (6.2.1) + connection_pool (>= 2.2.2) + rack (~> 2.0) + redis (>= 4.2.0) simple_form (5.1.0) actionpack (>= 5.2) activemodel (>= 5.2) @@ -314,6 +320,7 @@ DEPENDENCIES rubocop sass-rails (>= 6) selenium-webdriver + sidekiq simple_form simplecov slim-rails diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb new file mode 100644 index 0000000..5406ce2 --- /dev/null +++ b/config/initializers/sidekiq.rb @@ -0,0 +1,7 @@ +Sidekiq.configure_server do |config| + config.redis = { url: ENV['REDIS_URL'] } + end + + Sidekiq.configure_client do |config| + config.redis = { url: ENV['REDIS_URL'] } + end \ No newline at end of file diff --git a/config/sidekiq.yml b/config/sidekiq.yml new file mode 100644 index 0000000..287bc9c --- /dev/null +++ b/config/sidekiq.yml @@ -0,0 +1,4 @@ +:concurrency: 5 +:verbose: true +:queues: + - default \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 54750f5..c4dadba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,8 @@ services: - 3002:3002 depends_on: - db + - redis + - sidekiq environment: &web-environment BUNDLE_PATH: /bundle_cache GEM_HOME: /bundle_cache @@ -33,5 +35,16 @@ services: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + redis: + image: redis:5.0.9-alpine + + sidekiq: + build: . + command: bundle exec sidekiq -C /task_manager/config/sidekiq.yml + environment: *web-environment + volumes: *web-volumes + depends_on: + - redis + volumes: bundle_cache: diff --git a/test/test_helper.rb b/test/test_helper.rb index 0b88bed..8105dfc 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,5 @@ require 'simplecov' +require 'sidekiq/testing' SimpleCov.start ENV['RAILS_ENV'] ||= 'test' From 2cd08e3c4c30d9129be235bf4cf76fb2c4592c8b Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 03:23:13 -0700 Subject: [PATCH 2/7] rails updated to 6.0.4 because of mimemagic error --- Gemfile | 2 +- Gemfile.lock | 140 +++++++++++++++++++++++++-------------------------- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/Gemfile b/Gemfile index d8790e5..81f2242 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.7.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 6.0.3', '>= 6.0.3.4' +gem 'rails', '~> 6.0.3', '>= 6.0.3.6' # Use postgresql as the database for Active Record gem 'pg', '>= 0.18', '< 2.0' # Use Puma as the app server diff --git a/Gemfile.lock b/Gemfile.lock index b0589be..3e32a3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,38 +10,38 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.0.3.4) - actionpack (= 6.0.3.4) + actioncable (6.0.4) + actionpack (= 6.0.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3.4) - actionpack (= 6.0.3.4) - activejob (= 6.0.3.4) - activerecord (= 6.0.3.4) - activestorage (= 6.0.3.4) - activesupport (= 6.0.3.4) + actionmailbox (6.0.4) + actionpack (= 6.0.4) + activejob (= 6.0.4) + activerecord (= 6.0.4) + activestorage (= 6.0.4) + activesupport (= 6.0.4) mail (>= 2.7.1) - actionmailer (6.0.3.4) - actionpack (= 6.0.3.4) - actionview (= 6.0.3.4) - activejob (= 6.0.3.4) + actionmailer (6.0.4) + actionpack (= 6.0.4) + actionview (= 6.0.4) + activejob (= 6.0.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.3.4) - actionview (= 6.0.3.4) - activesupport (= 6.0.3.4) + actionpack (6.0.4) + actionview (= 6.0.4) + activesupport (= 6.0.4) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.3.4) - actionpack (= 6.0.3.4) - activerecord (= 6.0.3.4) - activestorage (= 6.0.3.4) - activesupport (= 6.0.3.4) + actiontext (6.0.4) + actionpack (= 6.0.4) + activerecord (= 6.0.4) + activestorage (= 6.0.4) + activesupport (= 6.0.4) nokogiri (>= 1.8.5) - actionview (6.0.3.4) - activesupport (= 6.0.3.4) + actionview (6.0.4) + activesupport (= 6.0.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -51,20 +51,20 @@ GEM activemodel (>= 4.1, < 6.2) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (6.0.3.4) - activesupport (= 6.0.3.4) + activejob (6.0.4) + activesupport (= 6.0.4) globalid (>= 0.3.6) - activemodel (6.0.3.4) - activesupport (= 6.0.3.4) - activerecord (6.0.3.4) - activemodel (= 6.0.3.4) - activesupport (= 6.0.3.4) - activestorage (6.0.3.4) - actionpack (= 6.0.3.4) - activejob (= 6.0.3.4) - activerecord (= 6.0.3.4) - marcel (~> 0.3.1) - activesupport (6.0.3.4) + activemodel (6.0.4) + activesupport (= 6.0.4) + activerecord (6.0.4) + activemodel (= 6.0.4) + activesupport (= 6.0.4) + activestorage (6.0.4) + actionpack (= 6.0.4) + activejob (= 6.0.4) + activerecord (= 6.0.4) + marcel (~> 1.0.0) + activesupport (6.0.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -93,11 +93,11 @@ GEM case_transform (0.2) activesupport childprocess (3.0.0) - concurrent-ruby (1.1.7) + concurrent-ruby (1.1.9) connection_pool (2.2.5) crass (1.0.6) docile (1.4.0) - erubi (1.9.0) + erubi (1.10.0) factory_bot (6.1.0) activesupport (>= 5.0.0) factory_bot_rails (6.1.0) @@ -106,7 +106,7 @@ GEM ffi (1.13.1) globalid (0.4.2) activesupport (>= 4.2.0) - i18n (1.8.5) + i18n (1.8.10) concurrent-ruby (~> 1.0) jbuilder (2.10.1) activesupport (>= 5.0.0) @@ -136,23 +136,22 @@ GEM listen (3.2.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.7.0) + loofah (2.10.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) + marcel (1.0.1) method_source (1.0.0) - mimemagic (0.3.5) - mini_mime (1.0.2) - mini_portile2 (2.4.0) - minitest (5.14.2) + mini_mime (1.1.0) + mini_portile2 (2.5.3) + minitest (5.14.4) msgpack (1.3.3) newrelic_rpm (7.1.0) - nio4r (2.5.4) - nokogiri (1.10.10) - mini_portile2 (~> 2.4.0) + nio4r (2.5.7) + nokogiri (1.11.7) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) parallel (1.20.1) parser (3.0.1.0) ast (~> 2.4.1) @@ -160,39 +159,40 @@ GEM public_suffix (4.0.6) puma (4.3.6) nio4r (~> 2.0) + racc (1.5.2) rack (2.2.3) rack-proxy (0.6.5) rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.3.4) - actioncable (= 6.0.3.4) - actionmailbox (= 6.0.3.4) - actionmailer (= 6.0.3.4) - actionpack (= 6.0.3.4) - actiontext (= 6.0.3.4) - actionview (= 6.0.3.4) - activejob (= 6.0.3.4) - activemodel (= 6.0.3.4) - activerecord (= 6.0.3.4) - activestorage (= 6.0.3.4) - activesupport (= 6.0.3.4) + rails (6.0.4) + actioncable (= 6.0.4) + actionmailbox (= 6.0.4) + actionmailer (= 6.0.4) + actionpack (= 6.0.4) + actiontext (= 6.0.4) + actionview (= 6.0.4) + activejob (= 6.0.4) + activemodel (= 6.0.4) + activerecord (= 6.0.4) + activestorage (= 6.0.4) + activesupport (= 6.0.4) bundler (>= 1.3.0) - railties (= 6.0.3.4) + railties (= 6.0.4) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (6.0.3.4) - actionpack (= 6.0.3.4) - activesupport (= 6.0.3.4) + railties (6.0.4) + actionpack (= 6.0.4) + activesupport (= 6.0.4) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rainbow (3.0.0) - rake (13.0.1) + rake (13.0.3) rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) @@ -264,10 +264,10 @@ GEM activerecord (>= 5.1) state_machines-activemodel (>= 0.8.0) temple (0.8.2) - thor (1.0.1) + thor (1.1.0) thread_safe (0.3.6) tilt (2.0.10) - tzinfo (1.2.7) + tzinfo (1.2.9) thread_safe (~> 0.1) unicode-display_width (2.0.0) uniform_notifier (1.14.2) @@ -286,12 +286,12 @@ GEM railties (>= 4.2) webpacker-react (0.3.2) webpacker - websocket-driver (0.7.3) + websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.4.0) + zeitwerk (2.4.2) PLATFORMS ruby @@ -313,7 +313,7 @@ DEPENDENCIES newrelic_rpm pg (>= 0.18, < 2.0) puma (~> 4.1) - rails (~> 6.0.3, >= 6.0.3.4) + rails (~> 6.0.3, >= 6.0.3.6) ransack! responders rollbar From f32e517a555545b129b57ffbdab7b13d06c8c8bb Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 03:36:42 -0700 Subject: [PATCH 3/7] added background mails delivery --- app/controllers/api/v1/tasks_controller.rb | 6 +++--- app/models/user.rb | 2 +- config/application.rb | 1 + config/sidekiq.yml | 3 ++- test/mailers/user_mailer_test.rb | 6 +++--- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/v1/tasks_controller.rb b/app/controllers/api/v1/tasks_controller.rb index 6015f09..431b8da 100644 --- a/app/controllers/api/v1/tasks_controller.rb +++ b/app/controllers/api/v1/tasks_controller.rb @@ -21,7 +21,7 @@ def create task = current_user.my_tasks.new(p) if task.save - UserMailer.with({ user: current_user, task: task }).task_created.deliver_now + UserMailer.with({ user: current_user, task: task }).task_created.deliver_later end respond_with(task, serializer: TaskSerializer, location: nil) @@ -31,7 +31,7 @@ def update task = Task.find(params[:id]) if task.update(task_params) - UserMailer.with({ task: task }).task_updated.deliver_now + UserMailer.with({ task: task }).task_updated.deliver_later end respond_with(task, serializer: TaskSerializer) @@ -41,7 +41,7 @@ def destroy task = Task.find(params[:id]) if task.destroy - UserMailer.with({ task: task }).task_updated.deliver_now + UserMailer.with({ task: task }).task_updated.deliver_later end respond_with(task) diff --git a/app/models/user.rb b/app/models/user.rb index 195414d..6d6fd4b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,7 +12,7 @@ def send_password_reset generate_token(:password_reset_token) self.password_reset_sent_at = Time.zone.now save! - UserMailer.with(self).forgot_password.deliver_now + UserMailer.with(self).forgot_password.deliver_later end def generate_token(column) diff --git a/config/application.rb b/config/application.rb index bb6d0af..ed7ff18 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,5 +16,6 @@ class Application < Rails::Application # Application configuration can go into files in config/initializers # -- all .rb files in that directory are automatically loaded after loading # the framework and any gems in your application. + config.active_job.queue_adapter = :sidekiq end end diff --git a/config/sidekiq.yml b/config/sidekiq.yml index 287bc9c..20aa386 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -1,4 +1,5 @@ :concurrency: 5 :verbose: true :queues: - - default \ No newline at end of file + - default + - mailers diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb index 0eaf8fe..388aad2 100644 --- a/test/mailers/user_mailer_test.rb +++ b/test/mailers/user_mailer_test.rb @@ -8,7 +8,7 @@ class UserMailerTest < ActionMailer::TestCase email = UserMailer.with(params).task_created assert_emails 1 do - email.deliver_now + email.deliver_later end assert_equal ['noreply@taskmanager.com'], email.from @@ -24,7 +24,7 @@ class UserMailerTest < ActionMailer::TestCase email = UserMailer.with(params).task_updated assert_emails 1 do - email.deliver_now + email.deliver_later end assert_equal ['noreply@taskmanager.com'], email.from @@ -40,7 +40,7 @@ class UserMailerTest < ActionMailer::TestCase email = UserMailer.with(params).task_deleted assert_emails 1 do - email.deliver_now + email.deliver_later end assert_equal ['noreply@taskmanager.com'], email.from From a8a8eec1d7c3e6e02eac30e73782a92e48873e12 Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 03:39:31 -0700 Subject: [PATCH 4/7] added END variable REDIS_URL --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index c4dadba..1610a4c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: DATABASE_HOST: db DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres + REDIS_URL: redis://redis command: bundle exec rails s -b '0.0.0.0' -p 3000 db: From c9bc1796a3aa29f36fbc718b7f00d3acd1223112 Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 05:05:39 -0700 Subject: [PATCH 5/7] added mails sending limit --- Gemfile | 2 ++ Gemfile.lock | 9 +++++++++ app/controllers/api/v1/tasks_controller.rb | 6 +++--- app/jobs/application_job.rb | 11 ++++------- app/jobs/send_forgot_password_notification_job.rb | 11 +++++++++++ app/jobs/send_task_create_notification_job.rb | 11 +++++++++++ app/jobs/send_task_destroy_notification_job.rb | 11 +++++++++++ app/jobs/send_task_update_notification_job.rb | 11 +++++++++++ app/mailers/user_mailer.rb | 7 ++++--- app/models/user.rb | 2 +- app/views/user_mailer/task_deleted.html.slim | 2 +- config/initializers/sidekiq.rb | 10 +++++++++- config/routes.rb | 1 + docker-compose.yml | 2 +- test/mailers/user_mailer_test.rb | 2 +- test/test_helper.rb | 1 + 16 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 app/jobs/send_forgot_password_notification_job.rb create mode 100644 app/jobs/send_task_create_notification_job.rb create mode 100644 app/jobs/send_task_destroy_notification_job.rb create mode 100644 app/jobs/send_task_update_notification_job.rb diff --git a/Gemfile b/Gemfile index 81f2242..c1aec14 100644 --- a/Gemfile +++ b/Gemfile @@ -69,3 +69,5 @@ gem 'js-routes' gem 'rollbar' gem 'newrelic_rpm' gem 'sidekiq' +gem 'sidekiq-failures' +gem 'sidekiq-throttled' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 3e32a3a..affded0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -197,6 +197,7 @@ GEM rb-inotify (0.10.1) ffi (~> 1.0) redis (4.3.1) + redis-prescription (1.0.0) regexp_parser (1.8.2) responders (3.0.1) actionpack (>= 5.0) @@ -233,6 +234,12 @@ GEM connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) + sidekiq-failures (1.0.0) + sidekiq (>= 4.0.0) + sidekiq-throttled (0.13.0) + concurrent-ruby + redis-prescription + sidekiq simple_form (5.1.0) actionpack (>= 5.2) activemodel (>= 5.2) @@ -321,6 +328,8 @@ DEPENDENCIES sass-rails (>= 6) selenium-webdriver sidekiq + sidekiq-failures + sidekiq-throttled simple_form simplecov slim-rails diff --git a/app/controllers/api/v1/tasks_controller.rb b/app/controllers/api/v1/tasks_controller.rb index 431b8da..9239673 100644 --- a/app/controllers/api/v1/tasks_controller.rb +++ b/app/controllers/api/v1/tasks_controller.rb @@ -21,7 +21,7 @@ def create task = current_user.my_tasks.new(p) if task.save - UserMailer.with({ user: current_user, task: task }).task_created.deliver_later + SendTaskCreateNotificationJob.perform_async(task.id) end respond_with(task, serializer: TaskSerializer, location: nil) @@ -31,7 +31,7 @@ def update task = Task.find(params[:id]) if task.update(task_params) - UserMailer.with({ task: task }).task_updated.deliver_later + SendTaskUpdateNotificationJob.perform_async(task.id) end respond_with(task, serializer: TaskSerializer) @@ -41,7 +41,7 @@ def destroy task = Task.find(params[:id]) if task.destroy - UserMailer.with({ task: task }).task_updated.deliver_later + SendTaskDestroyNotificationJob.perform_async(task.id, task.author_id) end respond_with(task) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index d394c3d..a8288af 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -1,7 +1,4 @@ -class ApplicationJob < ActiveJob::Base - # Automatically retry jobs that encountered a deadlock - # retry_on ActiveRecord::Deadlocked - - # Most jobs are safe to ignore if the underlying records are no longer available - # discard_on ActiveJob::DeserializationError -end +class ApplicationJob + include Sidekiq::Worker + include Sidekiq::Throttled::Worker +end \ No newline at end of file diff --git a/app/jobs/send_forgot_password_notification_job.rb b/app/jobs/send_forgot_password_notification_job.rb new file mode 100644 index 0000000..c194192 --- /dev/null +++ b/app/jobs/send_forgot_password_notification_job.rb @@ -0,0 +1,11 @@ +class SendForgotPasswordNotificationJob < ApplicationJob + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + + def perform(user_id) + user = User.find_by(id: user_id) + return if user.blank? + + UserMailer.with(user: user).forgot_password.deliver_now + end + end \ No newline at end of file diff --git a/app/jobs/send_task_create_notification_job.rb b/app/jobs/send_task_create_notification_job.rb new file mode 100644 index 0000000..8ae9101 --- /dev/null +++ b/app/jobs/send_task_create_notification_job.rb @@ -0,0 +1,11 @@ +class SendTaskCreateNotificationJob < ApplicationJob + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + + def perform(task_id) + task = Task.find_by(id: task_id) + return if task.blank? + + UserMailer.with(user: task.author, task: task).task_created.deliver_now + end + end \ No newline at end of file diff --git a/app/jobs/send_task_destroy_notification_job.rb b/app/jobs/send_task_destroy_notification_job.rb new file mode 100644 index 0000000..86fe9b5 --- /dev/null +++ b/app/jobs/send_task_destroy_notification_job.rb @@ -0,0 +1,11 @@ +class SendTaskDestroyNotificationJob < ApplicationJob + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + + def perform(task_id, user_id) + user = User.find_by(id: user_id) + return if user.blank? + + UserMailer.with({ user: user, task_id: task_id }).task_deleted.deliver_now + end + end \ No newline at end of file diff --git a/app/jobs/send_task_update_notification_job.rb b/app/jobs/send_task_update_notification_job.rb new file mode 100644 index 0000000..ac2e97b --- /dev/null +++ b/app/jobs/send_task_update_notification_job.rb @@ -0,0 +1,11 @@ +class SendTaskUpdateNotificationJob < ApplicationJob + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + + def perform(task_id) + task = Task.find_by(id: task_id) + return if task.blank? + + UserMailer.with({ task: task }).task_updated.deliver_now + end + end \ No newline at end of file diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index d39eddd..0fbf07b 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -15,9 +15,10 @@ def task_updated end def task_deleted - @task = params[:task] - - mail(from: 'noreply@taskmanager.com', to: @task.author.email, subject: 'Task Deleted') + user = params[:user] + @task_id = params[:task_id] + + mail(from: 'noreply@taskmanager.com', to: user.email, subject: 'Task Deleted') end def forgot_password diff --git a/app/models/user.rb b/app/models/user.rb index 6d6fd4b..f4a1990 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,7 +12,7 @@ def send_password_reset generate_token(:password_reset_token) self.password_reset_sent_at = Time.zone.now save! - UserMailer.with(self).forgot_password.deliver_later + SendForgotPasswordNotificationJob.perform_async(self.id) end def generate_token(column) diff --git a/app/views/user_mailer/task_deleted.html.slim b/app/views/user_mailer/task_deleted.html.slim index 1c2923c..2fe3072 100644 --- a/app/views/user_mailer/task_deleted.html.slim +++ b/app/views/user_mailer/task_deleted.html.slim @@ -1 +1 @@ -| Task #{@task.id} was deleted \ No newline at end of file +| Task #{@task_id} was deleted \ No newline at end of file diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 5406ce2..98dd067 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,7 +1,15 @@ +require 'sidekiq/web' +require "sidekiq/throttled" +require "sidekiq/throttled/web" + Sidekiq.configure_server do |config| config.redis = { url: ENV['REDIS_URL'] } end Sidekiq.configure_client do |config| config.redis = { url: ENV['REDIS_URL'] } - end \ No newline at end of file + end + + Sidekiq::Throttled::Registry.add(:mailer, { threshold: { limit: 1, period: 5.seconds } }) + + Sidekiq::Throttled.setup! \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1005493..952cacb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development? + mount Sidekiq::Web => '/admin/sidekiq' root :to => "web/boards#show" scope module: :web do diff --git a/docker-compose.yml b/docker-compose.yml index 1610a4c..0b69fb3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: sidekiq: build: . - command: bundle exec sidekiq -C /task_manager/config/sidekiq.yml + command: bundle exec sidekiq -C config/sidekiq.yml environment: *web-environment volumes: *web-volumes depends_on: diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb index 388aad2..d4a6534 100644 --- a/test/mailers/user_mailer_test.rb +++ b/test/mailers/user_mailer_test.rb @@ -36,7 +36,7 @@ class UserMailerTest < ActionMailer::TestCase test 'task deleted' do user = create(:user) task = create(:task, author: user) - params = { task: task } + params = { user: user, task_id: task.id } email = UserMailer.with(params).task_deleted assert_emails 1 do diff --git a/test/test_helper.rb b/test/test_helper.rb index 8105dfc..51bcddf 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -16,5 +16,6 @@ class ActiveSupport::TestCase # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all + Sidekiq::Testing.inline! # Add more helper methods to be used by all tests here... end From 482b16c6651e08388ad184eec8ccb21b44684734 Mon Sep 17 00:00:00 2001 From: the38th Date: Fri, 18 Jun 2021 06:01:48 -0700 Subject: [PATCH 6/7] added uniqness configure --- Gemfile | 3 ++- Gemfile.lock | 5 +++++ app/jobs/send_task_update_notification_job.rb | 1 + config/initializers/sidekiq.rb | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index c1aec14..8066a13 100644 --- a/Gemfile +++ b/Gemfile @@ -70,4 +70,5 @@ gem 'rollbar' gem 'newrelic_rpm' gem 'sidekiq' gem 'sidekiq-failures' -gem 'sidekiq-throttled' \ No newline at end of file +gem 'sidekiq-throttled' +gem 'sidekiq-unique-jobs', '~> 6.0.13' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index affded0..f3d1874 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -240,6 +240,10 @@ GEM concurrent-ruby redis-prescription sidekiq + sidekiq-unique-jobs (6.0.25) + concurrent-ruby (~> 1.0, >= 1.0.5) + sidekiq (>= 4.0, < 7.0) + thor (>= 0.20, < 2.0) simple_form (5.1.0) actionpack (>= 5.2) activemodel (>= 5.2) @@ -330,6 +334,7 @@ DEPENDENCIES sidekiq sidekiq-failures sidekiq-throttled + sidekiq-unique-jobs (~> 6.0.13) simple_form simplecov slim-rails diff --git a/app/jobs/send_task_update_notification_job.rb b/app/jobs/send_task_update_notification_job.rb index ac2e97b..445492b 100644 --- a/app/jobs/send_task_update_notification_job.rb +++ b/app/jobs/send_task_update_notification_job.rb @@ -1,6 +1,7 @@ class SendTaskUpdateNotificationJob < ApplicationJob sidekiq_options queue: :mailers sidekiq_throttle_as :mailer + sidekiq_options lock: :until_and_while_executing, on_conflict: { client: :log, server: :reject } def perform(task_id) task = Task.find_by(id: task_id) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 98dd067..0aa9a3b 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,6 +1,7 @@ require 'sidekiq/web' require "sidekiq/throttled" require "sidekiq/throttled/web" +require 'sidekiq_unique_jobs/web' Sidekiq.configure_server do |config| config.redis = { url: ENV['REDIS_URL'] } From 3fb28d4d590c650d5d0d090e9955b58a69c028d7 Mon Sep 17 00:00:00 2001 From: the38th Date: Sat, 19 Jun 2021 03:09:08 -0700 Subject: [PATCH 7/7] rubocop fixes --- Gemfile | 2 +- app/jobs/application_job.rb | 2 +- .../send_forgot_password_notification_job.rb | 18 ++++++++--------- app/jobs/send_task_create_notification_job.rb | 20 +++++++++---------- .../send_task_destroy_notification_job.rb | 18 ++++++++--------- app/jobs/send_task_update_notification_job.rb | 20 +++++++++---------- app/mailers/user_mailer.rb | 2 +- app/models/user.rb | 2 +- 8 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Gemfile b/Gemfile index 8066a13..f5631d3 100644 --- a/Gemfile +++ b/Gemfile @@ -71,4 +71,4 @@ gem 'newrelic_rpm' gem 'sidekiq' gem 'sidekiq-failures' gem 'sidekiq-throttled' -gem 'sidekiq-unique-jobs', '~> 6.0.13' \ No newline at end of file +gem 'sidekiq-unique-jobs', '~> 6.0.13' diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index a8288af..2641584 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -1,4 +1,4 @@ class ApplicationJob include Sidekiq::Worker include Sidekiq::Throttled::Worker -end \ No newline at end of file +end diff --git a/app/jobs/send_forgot_password_notification_job.rb b/app/jobs/send_forgot_password_notification_job.rb index c194192..49b0ad0 100644 --- a/app/jobs/send_forgot_password_notification_job.rb +++ b/app/jobs/send_forgot_password_notification_job.rb @@ -1,11 +1,11 @@ class SendForgotPasswordNotificationJob < ApplicationJob - sidekiq_options queue: :mailers - sidekiq_throttle_as :mailer - - def perform(user_id) - user = User.find_by(id: user_id) - return if user.blank? + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer - UserMailer.with(user: user).forgot_password.deliver_now - end - end \ No newline at end of file + def perform(user_id) + user = User.find_by(id: user_id) + return if user.blank? + + UserMailer.with(user: user).forgot_password.deliver_now + end +end diff --git a/app/jobs/send_task_create_notification_job.rb b/app/jobs/send_task_create_notification_job.rb index 8ae9101..b7105eb 100644 --- a/app/jobs/send_task_create_notification_job.rb +++ b/app/jobs/send_task_create_notification_job.rb @@ -1,11 +1,11 @@ class SendTaskCreateNotificationJob < ApplicationJob - sidekiq_options queue: :mailers - sidekiq_throttle_as :mailer - - def perform(task_id) - task = Task.find_by(id: task_id) - return if task.blank? - - UserMailer.with(user: task.author, task: task).task_created.deliver_now - end - end \ No newline at end of file + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + + def perform(task_id) + task = Task.find_by(id: task_id) + return if task.blank? + + UserMailer.with(user: task.author, task: task).task_created.deliver_now + end +end diff --git a/app/jobs/send_task_destroy_notification_job.rb b/app/jobs/send_task_destroy_notification_job.rb index 86fe9b5..cef34c2 100644 --- a/app/jobs/send_task_destroy_notification_job.rb +++ b/app/jobs/send_task_destroy_notification_job.rb @@ -1,11 +1,11 @@ class SendTaskDestroyNotificationJob < ApplicationJob - sidekiq_options queue: :mailers - sidekiq_throttle_as :mailer - - def perform(task_id, user_id) - user = User.find_by(id: user_id) - return if user.blank? + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer - UserMailer.with({ user: user, task_id: task_id }).task_deleted.deliver_now - end - end \ No newline at end of file + def perform(task_id, user_id) + user = User.find_by(id: user_id) + return if user.blank? + + UserMailer.with({ user: user, task_id: task_id }).task_deleted.deliver_now + end +end diff --git a/app/jobs/send_task_update_notification_job.rb b/app/jobs/send_task_update_notification_job.rb index 445492b..49ce0fc 100644 --- a/app/jobs/send_task_update_notification_job.rb +++ b/app/jobs/send_task_update_notification_job.rb @@ -1,12 +1,12 @@ class SendTaskUpdateNotificationJob < ApplicationJob - sidekiq_options queue: :mailers - sidekiq_throttle_as :mailer - sidekiq_options lock: :until_and_while_executing, on_conflict: { client: :log, server: :reject } - - def perform(task_id) - task = Task.find_by(id: task_id) - return if task.blank? + sidekiq_options queue: :mailers + sidekiq_throttle_as :mailer + sidekiq_options lock: :until_and_while_executing, on_conflict: { client: :log, server: :reject } - UserMailer.with({ task: task }).task_updated.deliver_now - end - end \ No newline at end of file + def perform(task_id) + task = Task.find_by(id: task_id) + return if task.blank? + + UserMailer.with({ task: task }).task_updated.deliver_now + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 0fbf07b..c3acfc9 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -17,7 +17,7 @@ def task_updated def task_deleted user = params[:user] @task_id = params[:task_id] - + mail(from: 'noreply@taskmanager.com', to: user.email, subject: 'Task Deleted') end diff --git a/app/models/user.rb b/app/models/user.rb index f4a1990..328aa23 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,7 +12,7 @@ def send_password_reset generate_token(:password_reset_token) self.password_reset_sent_at = Time.zone.now save! - SendForgotPasswordNotificationJob.perform_async(self.id) + SendForgotPasswordNotificationJob.perform_async(id) end def generate_token(column)