diff --git a/Gemfile b/Gemfile index f29df35d..9e1ca17b 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,6 @@ gem "pg", "~> 1.5" gem "puma", "~> 6.5" gem "rack-flash3", "~> 1.0" gem "rackup", "~> 2.0" -gem "sidekiq", "~> 7.2" gem "sinatra", "~> 4.0" group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index ca866851..5eb87643 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,8 +98,6 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - redis-client (0.22.1) - connection_pool regexp_parser (2.10.0) rerun (0.14.0) listen (~> 3.0) @@ -131,11 +129,6 @@ GEM ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) securerandom (0.4.1) - sidekiq (7.2.4) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.19.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -190,7 +183,6 @@ DEPENDENCIES rerun (~> 0.0) rspec (~> 3.0) rubocop (~> 1.70) - sidekiq (~> 7.2) simplecov (~> 0.0) sinatra (~> 4.0) yard (>= 0.9.36, < 1.0) diff --git a/Procfile b/Procfile index a3e19e30..a124c360 100644 --- a/Procfile +++ b/Procfile @@ -1,6 +1,4 @@ # outboxer_load: bin/outboxer_load 100000 -# sidekiq: bundle exec sidekiq -C config/sidekiq.yml -r ./config/sidekiq.rb # outboxer_published_messages_deleter: bin/outboxer_published_messages_deleter # outboxer_publisher: bin/outboxer_publisher # outboxer_app: bundle exec rerun "rackup -p 4567" -outboxer_sidekiq_publisher_1: bin/outboxer_sidekiq_publisher diff --git a/app/jobs/event_created_job.rb b/app/jobs/event_created_job.rb deleted file mode 100644 index a27a94c4..00000000 --- a/app/jobs/event_created_job.rb +++ /dev/null @@ -1,57 +0,0 @@ -class EventCreatedJob - include Sidekiq::Job - - def self.perform_async(event_id, event_type) - can_handle?(event_type: event_type) ? super : nil - end - - def perform(event_id, event_type) - job_class_name = to_job_class_name(event_type: event_type) - - if job_class_name.nil? - Sidekiq.logger.debug("Could not get job class name from event type: #{event_type}") - - return - end - - job_class = job_class_name.safe_constantize - - if job_class.nil? - Sidekiq.logger.debug("Could not constantize job class name: #{job_class_name}") - - return - end - - job_class.perform_async(event_id, event_type) - end - - TYPE_REGEX = /\A(::)?([A-Z][\w]*::)*[A-Z][\w]*Event\z/ - - def to_job_class_name(event_type:) - self.class.can_handle?(event_type: event_type) ? event_type.sub(/Event\z/, "Job") : nil - end - - def self.can_handle?(event_type:) - # \A => start of string - # (::)? => optional leading :: - # ([A-Z]\w*::)* => zero or more namespace segments like Foo:: or FooBar:: - # [A-Z]\w* => final constant segment (starts with capital letter) - # Event\z => ends with 'Event', anchors to end of string - # - # Valid examples: - # ✔ ContactCreatedEvent - # ✔ ::ContactCreatedEvent - # ✔ Accountify::ContactCreatedEvent - # ✔ Accountify::Invoice::CreatedEvent - # ✔ MyApp::Domain::Event::UserSignedUpEvent - # - # Invalid examples: - # ✘ contactCreatedEvent # starts lowercase - # ✘ ContactCreated # missing 'Event' - # ✘ Event # just 'Event' - # ✘ 123::InvalidEvent # starts with digit - # ✘ Foo:: # incomplete constant - - /\A(::)?([A-Z][\w]*::)*[A-Z][\w]*Event\z/.match?(event_type) - end -end diff --git a/app/jobs/outboxer_integration/complete_test_job.rb b/app/jobs/outboxer_integration/complete_test_job.rb deleted file mode 100644 index f0c36932..00000000 --- a/app/jobs/outboxer_integration/complete_test_job.rb +++ /dev/null @@ -1,13 +0,0 @@ -module OutboxerIntegration - class CompleteTestJob - include Sidekiq::Job - - def perform(args) - TestService.complete( - user_id: args["user_id"], - tenant_id: args["tenant_id"], - id: args["id"], - lock_version: args["lock_version"]) - end - end -end diff --git a/app/jobs/outboxer_integration/test_started_job.rb b/app/jobs/outboxer_integration/test_started_job.rb deleted file mode 100644 index 78474605..00000000 --- a/app/jobs/outboxer_integration/test_started_job.rb +++ /dev/null @@ -1,11 +0,0 @@ -module OutboxerIntegration - class TestStartedJob - include Sidekiq::Job - - def perform(event_id, event_type) - test_started_event = event_type.safe_constantize.find(event_id) - - TestCompletedEvent.create!(body: { "test_id" => test_started_event.body["test_id"] }) - end - end -end diff --git a/bin/console b/bin/console index 9c0d8d8e..50683cd8 100755 --- a/bin/console +++ b/bin/console @@ -3,22 +3,12 @@ require "bundler/setup" require "outboxer" -require "sidekiq" require "irb" -Dir.glob(File.join(__dir__, "../app/models/**/*.rb")).each do |file| - require file -end - environment = ENV["RAILS_ENV"] || "development" db_config = Outboxer::Database.config(environment: environment, concurrency: 1) Outboxer::Database.connect(config: db_config) -Sidekiq.configure_client do |config| - redis_url = ENV["REDIS_URL"] || "redis://localhost:6379/0" - config.redis = { url: redis_url, size: 1 } -end - ActiveRecord::Base.logger = Logger.new($stdout) ActiveRecord::Base.logger.level = Logger::DEBUG diff --git a/bin/outboxer_load b/bin/outboxer_load index 8c0505c3..fe2e1a50 100755 --- a/bin/outboxer_load +++ b/bin/outboxer_load @@ -24,9 +24,18 @@ queued_messages_count = 0 while queued_messages_count < max_messages_count break if reader.wait_readable(0) && reader.gets.strip == "INT" - messageable_id = SecureRandom.hex(3) - Outboxer::Message.queue(messageable_type: "Event", messageable_id: messageable_id) - puts "queued message for Event::#{messageable_id}" + class Event + attr_accessor :id + + def initialize(id:) + @id = id + end + end + + messageable = Event.new(id: SecureRandom.hex(3)) + + Outboxer::Message.queue(messageable: messageable) + puts "queued message for #{messageable.class.name}/#{messageable.id}" queued_messages_count += 1 end diff --git a/bin/outboxer_publisher b/bin/outboxer_publisher index ecebe6fc..fb421489 100755 --- a/bin/outboxer_publisher +++ b/bin/outboxer_publisher @@ -1,9 +1,7 @@ #!/usr/bin/env ruby require "bundler/setup" -require "sidekiq" require "outboxer" -require_relative "../app/jobs/event_created_job" cli_options = Outboxer::Publisher.parse_cli_options(ARGV) environment = cli_options.delete(:environment) || ENV["APP_ENV"] || ENV["RAILS_ENV"] || "development" @@ -12,14 +10,6 @@ config = Outboxer::Publisher.config(environment: environment, path: config_path) options = Outboxer::Publisher::PUBLISH_MESSAGE_DEFAULTS.merge(config.merge(cli_options)) logger = Outboxer::Logger.new($stdout, level: options[:log_level]) -Sidekiq.configure_client do |client_config| - client_config.redis = { - url: ENV["REDIS_URL"] || "redis://localhost:6379", - size: options[:concurrency] - } - client_config.logger = logger -end - database_config = Outboxer::Database.config( environment: environment, concurrency: options[:concurrency]) @@ -34,7 +24,10 @@ begin heartbeat_interval: options[:heartbeat_interval], logger: logger ) do |message| - EventCreatedJob.perform_async(message[:messageable_id], message[:messageable_type]) + logger.info "Outboxer publishing message " \ + "id=#{message[:id]} " \ + "messageable_id=#{message[:messageable_id]} " \ + "messageable_type=#{message[:messageable_type]}" end ensure Outboxer::Database.disconnect(logger: logger) diff --git a/bin/sidekiq b/bin/sidekiq deleted file mode 100755 index e7af7e7e..00000000 --- a/bin/sidekiq +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# -# This file was generated by Bundler. -# -# The application 'sidekiq' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) - -bundle_binstub = File.expand_path("bundle", __dir__) - -if File.file?(bundle_binstub) - if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") - load(bundle_binstub) - else - abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. -Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") - end -end - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("sidekiq", "sidekiq") diff --git a/bin/sidekiqmon b/bin/sidekiqmon deleted file mode 100755 index 0c907984..00000000 --- a/bin/sidekiqmon +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# -# This file was generated by Bundler. -# -# The application 'sidekiqmon' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) - -bundle_binstub = File.expand_path("bundle", __dir__) - -if File.file?(bundle_binstub) - if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") - load(bundle_binstub) - else - abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. -Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") - end -end - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("sidekiq", "sidekiqmon") diff --git a/config.ru b/config.ru index 3b2dc37e..714c985f 100644 --- a/config.ru +++ b/config.ru @@ -4,20 +4,11 @@ require "dotenv/load" require "securerandom" require "sinatra" -require "sidekiq" -require "sidekiq/web" require "outboxer/web" -require_relative "app/models/application_record" -require_relative "app/models/event" - use Rack::Session::Cookie, secret: ENV.fetch("SESSION_SECRET", nil), same_site: true, max_age: 86_400 map "/outboxer" do run Outboxer::Web end - -map "/sidekiq" do - run Sidekiq::Web -end diff --git a/config/sidekiq.rb b/config/sidekiq.rb deleted file mode 100644 index 5e56f0d2..00000000 --- a/config/sidekiq.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "bundler/setup" -require "active_record" -require "sidekiq" - -require "outboxer" - -Dir[File.expand_path("../app/models/**/*.rb", __dir__)].each { |file| require file } -Dir[File.expand_path("../app/jobs/**/*.rb", __dir__)].each { |file| require file } -Dir[File.expand_path("../app/services/**/*.rb", __dir__)].each { |file| require file } - -environment = ENV["RAILS_ENV"] || "development" - -db_config_content = File.read("config/database.yml") -db_config_erb_result = ERB.new(db_config_content).result -db_config = YAML.safe_load(db_config_erb_result)[environment] - -ActiveRecord::Base.establish_connection(db_config.merge("pool" => 5)) - -redis_url = ENV["REDIS_URL"] || "redis://localhost:6379/0" - -Sidekiq.configure_server do |config| - config.redis = { url: redis_url } -end - -Sidekiq.configure_client do |config| - config.redis = { url: redis_url } -end diff --git a/db/migrate/create_outboxer_integration_tests.rb b/db/migrate/create_outboxer_integration_tests.rb deleted file mode 100644 index ca0a09f0..00000000 --- a/db/migrate/create_outboxer_integration_tests.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateOutboxerIntegrationTests < ActiveRecord::Migration[7.0] - def up - create_table :outboxer_integration_tests do |t| - t.bigint :tenant_id - - t.integer :lock_version, default: 0, null: false - - t.timestamps - end - end - - def down - drop_table :outboxer_integration_tests - end -end diff --git a/generators/install_generator.rb b/generators/install_generator.rb index e9688106..b84d3606 100644 --- a/generators/install_generator.rb +++ b/generators/install_generator.rb @@ -36,42 +36,6 @@ def copy_migrations migration_template( "db/migrate/create_outboxer_signals.rb", "db/migrate/create_outboxer_signals.rb") - - migration_template( - "db/migrate/create_events.rb", - "db/migrate/create_events.rb") - end - - def copy_models - copy_file( - "app/models/event.rb", - "app/models/event.rb") - - copy_file( - "app/models/outboxer_integration/test_started_event.rb", - "app/models/outboxer_integration/test_started_event.rb") - - copy_file( - "app/models/outboxer_integration/test_completed_event.rb", - "app/models/outboxer_integration/test_completed_event.rb") - end - - def copy_jobs - copy_file( - "app/jobs/event_created_job.rb", - "app/jobs/event_created_job.rb") - - copy_file( - "spec/jobs/event_created_job_spec.rb", - "spec/jobs/event_created_job_spec.rb") - - copy_file( - "app/jobs/outboxer_integration/test_started_job.rb", - "app/jobs/outboxer_integration/test_started_job.rb") - - copy_file( - "app/jobs/outboxer_integration/complete_test_job.rb", - "app/jobs/outboxer_integration/complete_test_job.rb") end def copy_bin_file diff --git a/lib/outboxer/message.rb b/lib/outboxer/message.rb index 470822f2..0095c570 100644 --- a/lib/outboxer/message.rb +++ b/lib/outboxer/message.rb @@ -11,14 +11,12 @@ module Message # @param messageable_id [Integer, nil] ID of the polymorphic messageable model # @param time [Time] time context for setting timestamps. # @return [Hash] a hash with message details including IDs and timestamps. - def queue(messageable: nil, - messageable_type: nil, messageable_id: nil, - time: ::Time) + def queue(messageable:, time: ::Time) current_utc_time = time.now.utc message = Models::Message.create!( - messageable_id: messageable&.id || messageable_id, - messageable_type: messageable&.class&.name || messageable_type, + messageable_id: messageable.id, + messageable_type: messageable.class.name, status: Message::Status::QUEUED, queued_at: current_utc_time, buffered_at: nil, diff --git a/lib/outboxer/web.rb b/lib/outboxer/web.rb index 571ab735..6bc508b6 100755 --- a/lib/outboxer/web.rb +++ b/lib/outboxer/web.rb @@ -607,8 +607,8 @@ def normalise_query_string(status: Message::LIST_STATUS_DEFAULT, message = Message.find_by_id(id: params[:id]) - messageable_class = Object.const_get(message[:messageable_type]) - messageable = messageable_class.find_by_id(id: message[:messageable_id]) + messageable_class = message[:messageable_type]&.safe_constantize + messageable = message && messageable_class&.find_by_id(id: message[:messageable_id]) erb :message, locals: { denormalised_query_params: denormalised_query_params, @@ -632,8 +632,8 @@ def normalise_query_string(status: Message::LIST_STATUS_DEFAULT, message = Message.find_by_id(id: params[:id]) messages_metrics = Message.metrics - messageable_class = Object.const_get(message[:messageable_type]) - messageable = messageable_class.find(message[:messageable_id]) + messageable_class = message[:messageable_type]&.safe_constantize + messageable = messageable_class&.find_by_id(id: message[:messageable_id]) erb :messageable, locals: { message: message, diff --git a/lib/outboxer/web/views/message.erb b/lib/outboxer/web/views/message.erb index 7d831253..cf827719 100644 --- a/lib/outboxer/web/views/message.erb +++ b/lib/outboxer/web/views/message.erb @@ -1,7 +1,7 @@