From 3f61386ee824b5c605d22342dac341721fe6d135 Mon Sep 17 00:00:00 2001 From: Robert Gradowski Date: Wed, 9 Oct 2024 18:54:25 +0200 Subject: [PATCH] remedy logic, gemfile, gemspec, CI --- .github/workflows/ci.yml | 37 ++++++++++ Gemfile | 7 +- Gemfile.lock | 87 +++++++++++++++++++++++ README.md | 6 +- lib/remedy/version.rb | 7 ++ lib/sidekiq/poison/pill/remedy.rb | 14 ---- lib/sidekiq/poison/pill/remedy/version.rb | 11 --- lib/sidekiq_poison_pill_remedy.rb | 41 +++++++++++ sidekiq-poison-pill-remedy.gemspec | 16 ++--- spec/sidekiq/poison/pill/remedy_spec.rb | 11 --- spec/sidekiq_poison_pill_remedy_spec.rb | 13 ++++ spec/spec_helper.rb | 4 +- 12 files changed, 203 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 Gemfile.lock create mode 100644 lib/remedy/version.rb delete mode 100644 lib/sidekiq/poison/pill/remedy.rb delete mode 100644 lib/sidekiq/poison/pill/remedy/version.rb create mode 100644 lib/sidekiq_poison_pill_remedy.rb delete mode 100644 spec/sidekiq/poison/pill/remedy_spec.rb create mode 100644 spec/sidekiq_poison_pill_remedy_spec.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ea773bd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI +on: [pull_request, push] +jobs: + rubocop: + strategy: + fail-fast: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.1 + bundler-cache: true + - run: bundle exec rubocop + rspec: + strategy: + fail-fast: false + matrix: + ruby: ['3.1', '3.2', '3.3'] + runs-on: ubuntu-latest + services: + redis: + image: redis + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - run: bundle exec rake \ No newline at end of file diff --git a/Gemfile b/Gemfile index 03278df..52bca7f 100644 --- a/Gemfile +++ b/Gemfile @@ -6,5 +6,10 @@ source "https://rubygems.org" gemspec gem "rake", "~> 13.0" - gem "rspec", "~> 3.0" +gem 'rubocop', '~> 1.40', require: false +gem "rubocop-performance" +gem "rubocop-rake" +gem "rubocop-rspec" +gem 'sidekiq' +gem 'sentry-ruby' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..101d0fb --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,87 @@ +PATH + remote: . + specs: + sidekiq-poison-pill-remedy (0.1.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + bigdecimal (3.1.8) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + diff-lcs (1.5.1) + json (2.7.2) + language_server-protocol (3.17.0.3) + logger (1.6.1) + parallel (1.26.3) + parser (3.3.5.0) + ast (~> 2.4.1) + racc + racc (1.8.1) + rack (3.1.7) + rainbow (3.1.1) + rake (13.2.1) + redis-client (0.22.2) + connection_pool + regexp_parser (2.9.2) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.1) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.66.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rubocop-ast (>= 1.32.2, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.32.3) + parser (>= 3.3.1.0) + rubocop-performance (1.22.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rake (0.6.0) + rubocop (~> 1.0) + rubocop-rspec (3.1.0) + rubocop (~> 1.61) + ruby-progressbar (1.13.0) + sentry-ruby (5.21.0) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + sidekiq (7.3.2) + concurrent-ruby (< 2) + connection_pool (>= 2.3.0) + logger + rack (>= 2.2.4) + redis-client (>= 0.22.2) + unicode-display_width (2.6.0) + +PLATFORMS + arm64-darwin-22 + +DEPENDENCIES + rake (~> 13.0) + rspec (~> 3.0) + rubocop (~> 1.40) + rubocop-performance + rubocop-rake + rubocop-rspec + sentry-ruby + sidekiq + sidekiq-poison-pill-remedy! + +BUNDLED WITH + 2.4.18 diff --git a/README.md b/README.md index cf430d3..0487ad8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -# Sidekiq::Poison::Pill::Remedy +# SidekiqPoisonPillRemedy -TODO: Delete this and the text below, and describe your gem - -Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sidekiq/poison/pill/remedy`. To experiment with that code, run `bin/console` for an interactive prompt. +The Sidekiq Poison Pill Remedy gem enhances Sidekiq's job processing by automatically handling and rescheduling failed jobs (poison pills) with integrated logging and error tracking through Sentry, ultimately improving reliability and performance optimization. ## Installation diff --git a/lib/remedy/version.rb b/lib/remedy/version.rb new file mode 100644 index 0000000..214cd96 --- /dev/null +++ b/lib/remedy/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module SidekiqPoisonPillRemedy + module Version + end + VERSION = '0.1.0' +end diff --git a/lib/sidekiq/poison/pill/remedy.rb b/lib/sidekiq/poison/pill/remedy.rb deleted file mode 100644 index 238011c..0000000 --- a/lib/sidekiq/poison/pill/remedy.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require_relative "remedy/version" - -module Sidekiq - module Poison - module Pill - module Remedy - class Error < StandardError; end - # Your code goes here... - end - end - end -end diff --git a/lib/sidekiq/poison/pill/remedy/version.rb b/lib/sidekiq/poison/pill/remedy/version.rb deleted file mode 100644 index 075ca78..0000000 --- a/lib/sidekiq/poison/pill/remedy/version.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Sidekiq - module Poison - module Pill - module Remedy - VERSION = "0.1.0" - end - end - end -end diff --git a/lib/sidekiq_poison_pill_remedy.rb b/lib/sidekiq_poison_pill_remedy.rb new file mode 100644 index 0000000..ef1c77c --- /dev/null +++ b/lib/sidekiq_poison_pill_remedy.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require_relative "../lib/remedy/version" + +module SidekiqPoisonPillRemedy + def self.remedy + Proc.new do |_jobstr, pill| + next unless pill + + job = Sidekiq::DeadSet.new.find_job(pill.jid) + + if job.queue == "poison_pill" + capture_sentry_message( + "#{job.klass} failed in the `#{job.queue}`, this means that it has to be urgently optimized on memory usage", + level: :critical, + job_item: job.item + ) + else + capture_sentry_message( + "#{job.klass} was marked as `poison pill`, please create the job memory optimizations ticket timely", + level: :warning, + job_item: job.item + ) + job.klass.constantize.set(queue: :poison_pill).perform_async(*job.args) + job.delete + end + end + end + + def self.capture_sentry_message(message, level:, job_item:) + if defined?(Sentry) + Sentry.capture_message( + message, + level: level, + extra: { job_item: job_item } + ) + end + + Sidekiq.logger.fatal(message) + end +end diff --git a/sidekiq-poison-pill-remedy.gemspec b/sidekiq-poison-pill-remedy.gemspec index 10c8182..993052a 100644 --- a/sidekiq-poison-pill-remedy.gemspec +++ b/sidekiq-poison-pill-remedy.gemspec @@ -1,24 +1,24 @@ # frozen_string_literal: true -require_relative "lib/sidekiq/poison/pill/remedy/version" +require_relative "lib/remedy/version" Gem::Specification.new do |spec| spec.name = "sidekiq-poison-pill-remedy" - spec.version = Sidekiq::Poison::Pill::Remedy::VERSION + spec.version = SidekiqPoisonPillRemedy::VERSION spec.authors = ["Karol Galanciak"] spec.email = ["karol.galanciak@gmail.com"] - spec.summary = "TODO: Write a short summary, because RubyGems requires one." - spec.description = "TODO: Write a longer description or delete this line." - spec.homepage = "TODO: Put your gem's website or public repo URL here." + spec.summary = "Enhances Sidekiq's job processing by automatically handling and rescheduling failed jobs (poison pills)" + spec.description = "Enhances Sidekiq's job processing by automatically handling and rescheduling failed jobs (poison pills)" + spec.homepage = "https://example.com" spec.license = "MIT" spec.required_ruby_version = ">= 3.0.0" - spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'" + # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'" spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." - spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." + spec.metadata["source_code_uri"] = "https://example.com" + spec.metadata["changelog_uri"] = "https://example.com" # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. diff --git a/spec/sidekiq/poison/pill/remedy_spec.rb b/spec/sidekiq/poison/pill/remedy_spec.rb deleted file mode 100644 index d159a00..0000000 --- a/spec/sidekiq/poison/pill/remedy_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Sidekiq::Poison::Pill::Remedy do - it "has a version number" do - expect(Sidekiq::Poison::Pill::Remedy::VERSION).not_to be nil - end - - it "does something useful" do - expect(false).to eq(true) - end -end diff --git a/spec/sidekiq_poison_pill_remedy_spec.rb b/spec/sidekiq_poison_pill_remedy_spec.rb new file mode 100644 index 0000000..3806335 --- /dev/null +++ b/spec/sidekiq_poison_pill_remedy_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require_relative '../lib/sidekiq_poison_pill_remedy' + +RSpec.describe SidekiqPoisonPillRemedy do + it 'has a version number' do + expect(SidekiqPoisonPillRemedy::VERSION).not_to be nil + end + + it 'does something useful' do + expect(false).to eq(true) + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 901a1e8..0b94aab 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -require "sidekiq/poison/pill/remedy" +require_relative '../lib/sidekiq_poison_pill_remedy' RSpec.configure do |config| # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" + config.example_status_persistence_file_path = '.rspec_status' # Disable RSpec exposing methods globally on `Module` and `main` config.disable_monkey_patching!