From 3013396610da1f393592c5aaeca441cb1fbb6066 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Mon, 6 Apr 2026 16:45:02 -0700 Subject: [PATCH 01/25] added support for ruby 3.4 added github workflows --- .circleci/config.yml | 117 +++++++++++------- .github/workflows/test.yaml | 92 ++++++++++++++ action_subscriber.gemspec | 10 +- config/action_subscriber.yml.sample | 12 ++ lib/action_subscriber/configuration.rb | 6 +- .../active_record/connection_management.rb | 2 +- lib/action_subscriber/version.rb | 2 +- .../connection_management_spec.rb | 2 +- spec/support/sample_config.yml | 18 +-- 9 files changed, 201 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/test.yaml create mode 100644 config/action_subscriber.yml.sample diff --git a/.circleci/config.yml b/.circleci/config.yml index 87672bc..91ecfa5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,63 +1,90 @@ -# Inspired by: http://mikebian.co/running-tests-against-multiple-ruby-versions-using-circleci/ - version: 2.1 -orbs: - ruby: circleci/ruby@1.1 - - - # If you want to work on `action_subscriber` you will need to have a rabbitmq instance running locally on port 5672 with a management plugin enabled on port 15672. Usually the easiest way to accomplish this is to use docker and run the command: - - # ``` - jobs: - test: - parallelism: 1 + build_and_test: parameters: - ruby-image: + docker_image: type: string + description: "The Ruby or JRuby Docker image to test against" + docker: - - image: << parameters.ruby-image >> - - image: rabbitmq:3.11-management + # 1. The Primary Container (where your code actually runs) + - image: << parameters.docker_image >> + environment: + JRUBY_OPTS: "-J-Xmx1024m" + RAILS_ENV: test + # Tell your app where to find RabbitMQ (if your app uses this ENV var) + RABBITMQ_URL: "amqp://guest:guest@localhost:5672" + + # 2. The Service Container (runs in the background) + - image: rabbitmq:3 + # If you need the management UI for debugging, use `rabbitmq:3-management` instead + # environment: + # RABBITMQ_DEFAULT_USER: guest + # RABBITMQ_DEFAULT_PASS: guest + + working_directory: ~/project steps: - - checkout - - run: - name: install dockerize - command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz - environment: - DOCKERIZE_VERSION: v0.3.0 - # - run: - # name: Wait for rabbitmq - # command: dockerize -wait tcp://localhost:5672 -timeout 1m - run: - name: Install bundler - command: gem install bundler + name: Install System Dependencies + command: | + if [ "$(id -u)" = "0" ]; then + apt-get update && apt-get install -y build-essential git + else + sudo apt-get update && sudo apt-get install -y build-essential git + fi + - checkout + # Note: We added the docker_image parameter to the cache key + # so MRI and JRuby gems don't conflict. + - restore_cache: + keys: + - v1-gems-<< parameters.docker_image >>-{{ checksum "Gemfile.lock" }} + - v1-gems-<< parameters.docker_image >>- + - run: - name: Which bundler? - command: bundle -v + name: Install Ruby Dependencies + command: | + gem install bundler + bundle config set --local path 'vendor/bundle' + bundle install --jobs=4 --retry=3 + + - save_cache: + paths: + - ./vendor/bundle + key: v1-gems-<< parameters.docker_image >>-{{ checksum "Gemfile.lock" }} + + # Wait for RabbitMQ to be ready before running tests. + # Service containers can sometimes take a few seconds to boot up. - run: - name: bundle install - command: bundle install + name: Wait for RabbitMQ + command: | + if [ "$(id -u)" = "0" ]; then + apt-get install -y netcat-openbsd + else + sudo apt-get install -y netcat-openbsd + fi + + echo "Waiting for RabbitMQ to start..." + while ! nc -z localhost 5672; do + sleep 1 + done + echo "RabbitMQ is ready!" + - run: - name: rspec + name: Run Tests command: bundle exec rspec -# strangely, there seems to be very little documentation about exactly how martix builds work. -# By defining a param inside your job definition, Circle CI will automatically spawn a job for -# unique param value passed via `matrix`. Neat! -# https://circleci.com/blog/circleci-matrix-jobs/ workflows: - build_and_test: + version: 2 + ruby_compatibility_matrix: jobs: - - test: + - build_and_test: + name: test-<< matrix.docker_image >> matrix: parameters: - ruby-image: - - circleci/ruby:2.6 - - circleci/ruby:2.7 - - cimg/ruby:3.0 - - cimg/ruby:3.1 - - circleci/jruby:9.2 - - circleci/jruby:9.3 - # - circleci/jruby:9.4 (TODO: Restore once this image exists) + docker_image: + - "cimg/ruby:3.1" + - "cimg/ruby:3.4" + - "jruby:9.4" + - "jruby:10" \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..3eb787a --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,92 @@ +name: Ruby Compatibility Matrix + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build_and_test: + name: test-${{ matrix.docker_image }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + docker_image: + - "ruby:3.1" + - "ruby:3.4" + - "jruby:9.4" + - "jruby:10" + + container: + image: ${{ matrix.docker_image }} + env: + JRUBY_OPTS: "-J-Xmx1024m" + RAILS_ENV: test + # Use the service name 'rabbitmq' as the host, not localhost + RABBITMQ_URL: "amqp://guest:guest@rabbitmq:5672" + RABBITMQ_HOST: rabbitmq + + services: + rabbitmq: + image: rabbitmq:3.12-management + env: + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest + # Note: Health checks here ensure the container is up before steps start + options: >- + --health-cmd "rabbitmq-diagnostics -q check_running" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install System Dependencies + run: | + if [ "$(id -u)" = "0" ]; then + apt-get update && apt-get install -y build-essential git netcat-openbsd + else + sudo apt-get update && sudo apt-get install -y build-essential git netcat-openbsd + fi + + - name: Cache Ruby Gems + uses: actions/cache@v4 + with: + path: vendor/bundle + key: v1-gems-${{ matrix.docker_image }}-${{ hashFiles('Gemfile.lock') }} + restore-keys: | + v1-gems-${{ matrix.docker_image }}- + + - name: Install Ruby Dependencies + run: | + gem install bundler + bundle config set --local path 'vendor/bundle' + bundle install --jobs=4 --retry=3 + + - name: Wait for RabbitMQ + run: | + echo "Waiting for RabbitMQ to start at hostname 'rabbitmq'..." + # Fix: Use the service name 'rabbitmq' instead of 'localhost' + for i in {1..30}; do + if nc -z rabbitmq 5672; then + echo "RabbitMQ is ready!" + exit 0 + fi + echo "Waiting... ($i/30)" + sleep 1 + done + echo "RabbitMQ failed to start" + exit 1 + + - name: Run Tests + run : | + echo "$PWD" + cp ./config/action_subscriber.yml.sample ./config/action_subscriber.yml + echo "$(ls -ltr config)" + + bundle exec rspec diff --git a/action_subscriber.gemspec b/action_subscriber.gemspec index 1e462f4..cb00e6e 100644 --- a/action_subscriber.gemspec +++ b/action_subscriber.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] - spec.add_dependency "activesupport", ">= 3.2" + spec.add_dependency "activesupport", ">= 6.0" if ENV["PLATFORM"] == "java" || ::RUBY_PLATFORM == "java" spec.platform = "java" @@ -30,12 +30,14 @@ Gem::Specification.new do |spec| spec.add_dependency "middleware" spec.add_dependency "thor" + spec.required_ruby_version = '>= 3.1.0' + spec.add_development_dependency "active_publisher", "~> 0.1.5" - spec.add_development_dependency "activerecord", ">= 3.2" - spec.add_development_dependency "bundler", ">= 1.6" + spec.add_development_dependency "activerecord", ">= 6.0" + spec.add_development_dependency "bundler" spec.add_development_dependency "pry-nav" spec.add_development_dependency "rabbitmq_http_api_client", "~> 1.15.0" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "rspec" spec.add_development_dependency "rake" spec.add_development_dependency "simplecov" end diff --git a/config/action_subscriber.yml.sample b/config/action_subscriber.yml.sample new file mode 100644 index 0000000..b9ad29d --- /dev/null +++ b/config/action_subscriber.yml.sample @@ -0,0 +1,12 @@ +--- +defaults: &defaults + heartbeat: 15 + host: rabbitmq + network_recovery_interval: 5 + port: 5672 + username: guest + password: guest + +production: *defaults +development: *defaults +test: *defaults diff --git a/lib/action_subscriber/configuration.rb b/lib/action_subscriber/configuration.rb index 5e67adc..832955c 100644 --- a/lib/action_subscriber/configuration.rb +++ b/lib/action_subscriber/configuration.rb @@ -67,11 +67,15 @@ def self.configure_from_yaml_and_cli(cli_options = {}, reload = false) yaml_config = {} absolute_config_path = ::File.expand_path(::File.join("config", "action_subscriber.yml")) - if ::File.exists?(absolute_config_path) + puts "Trying to look for config file at #{absolute_config_path}" + if ::File.exist?(absolute_config_path) + puts "config file exists, loading" erb_yaml = ::ERB.new(::File.read(absolute_config_path)).result # Defined in Psych 3.2+ and the new canonical way to load trusted documents: # https://github.com/ruby/psych/issues/533#issuecomment-1019363688 yaml_config = ::YAML.respond_to?(:unsafe_load) ? ::YAML.unsafe_load(erb_yaml)[env] : ::YAML.load(erb_yaml)[env] + else + puts "config file does not exist" end ::ActionSubscriber::Configuration::DEFAULTS.each_pair do |key, value| diff --git a/lib/action_subscriber/middleware/active_record/connection_management.rb b/lib/action_subscriber/middleware/active_record/connection_management.rb index 5b424e5..c4d2ab4 100644 --- a/lib/action_subscriber/middleware/active_record/connection_management.rb +++ b/lib/action_subscriber/middleware/active_record/connection_management.rb @@ -16,7 +16,7 @@ def self.start_timed_task! :execution_interval => ::ActionSubscriber.config.connection_reaping_interval, :timeout_interval => ::ActionSubscriber.config.connection_reaping_timeout_interval) do - ::ActiveRecord::Base.clear_active_connections! + ::ActiveRecord::Base.connection_handler.clear_active_connections! end timed_task.execute diff --git a/lib/action_subscriber/version.rb b/lib/action_subscriber/version.rb index a0a9d73..cdfa208 100644 --- a/lib/action_subscriber/version.rb +++ b/lib/action_subscriber/version.rb @@ -1,3 +1,3 @@ module ActionSubscriber - VERSION = "5.3.3" + VERSION = "5.4.0" end diff --git a/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb b/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb index 7053c02..5a1247f 100644 --- a/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb +++ b/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb @@ -6,7 +6,7 @@ before { pool = double("pool") allow(pool).to receive(:with_connection).and_yield - allow(ActiveRecord::Base).to receive(:clear_active_connections!) + allow(ActiveRecord::Base.connection_handler).to receive(:clear_active_connections!) allow(ActiveRecord::Base).to receive(:connection_pool).and_return(pool) } diff --git a/spec/support/sample_config.yml b/spec/support/sample_config.yml index b156fc4..b9ad29d 100644 --- a/spec/support/sample_config.yml +++ b/spec/support/sample_config.yml @@ -1,8 +1,12 @@ -development: - password: <%= "WAT" %> +--- +defaults: &defaults + heartbeat: 15 + host: rabbitmq + network_recovery_interval: 5 + port: 5672 + username: guest + password: guest -test: - password: <%= "WAT" %> - -production: - password: <%= "WAT" %> +production: *defaults +development: *defaults +test: *defaults From 3ff1d25b7e847218fb787c481320e20ae7768df8 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:28:59 -0700 Subject: [PATCH 02/25] testing with rabbitmq instead of localhost --- lib/action_subscriber/configuration.rb | 2 +- lib/action_subscriber/rabbit_connection.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/action_subscriber/configuration.rb b/lib/action_subscriber/configuration.rb index 832955c..9e4b8ec 100644 --- a/lib/action_subscriber/configuration.rb +++ b/lib/action_subscriber/configuration.rb @@ -37,7 +37,7 @@ class Configuration :connection_reaping_timeout_interval => 5, :default_exchange => 'events', :heartbeat => 5, - :host => 'localhost', + :host => 'rabbitmq', :hosts => [], :network_recovery_interval => NETWORK_RECOVERY_INTERVAL, :password => "guest", diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index f6ca0e3..12be270 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -29,6 +29,7 @@ def self.create_connection options[:executor_factory] = ::Proc.new do ::MarchHare::ThreadPools.fixed_of_size(options[:threadpool_size]) end + puts "RabbitConnection#create_connection options=#{options}" connection = ::MarchHare.connect(options) connection.on_blocked do |reason| on_blocked(reason) From 7fd715f239f35380b794ec53397bdf8a607dce1f Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:29:42 -0700 Subject: [PATCH 03/25] less images for circleci --- .circleci/config.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 91ecfa5..abbb465 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -84,7 +84,4 @@ workflows: matrix: parameters: docker_image: - - "cimg/ruby:3.1" - - "cimg/ruby:3.4" - - "jruby:9.4" - - "jruby:10" \ No newline at end of file + - "cimg/ruby:3.1" \ No newline at end of file From 825cdc71a8757fd43e0888a340c87452c0075873 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:31:37 -0700 Subject: [PATCH 04/25] try non normal username/password --- .github/workflows/test.yaml | 6 +++--- config/action_subscriber.yml.sample | 4 ++-- spec/support/sample_config.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3eb787a..3c7b593 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,15 +26,15 @@ jobs: JRUBY_OPTS: "-J-Xmx1024m" RAILS_ENV: test # Use the service name 'rabbitmq' as the host, not localhost - RABBITMQ_URL: "amqp://guest:guest@rabbitmq:5672" + RABBITMQ_URL: "amqp://demo:demo@rabbitmq:5672" RABBITMQ_HOST: rabbitmq services: rabbitmq: image: rabbitmq:3.12-management env: - RABBITMQ_DEFAULT_USER: guest - RABBITMQ_DEFAULT_PASS: guest + RABBITMQ_DEFAULT_USER: demo + RABBITMQ_DEFAULT_PASS: demo # Note: Health checks here ensure the container is up before steps start options: >- --health-cmd "rabbitmq-diagnostics -q check_running" diff --git a/config/action_subscriber.yml.sample b/config/action_subscriber.yml.sample index b9ad29d..39caa8a 100644 --- a/config/action_subscriber.yml.sample +++ b/config/action_subscriber.yml.sample @@ -4,8 +4,8 @@ defaults: &defaults host: rabbitmq network_recovery_interval: 5 port: 5672 - username: guest - password: guest + username: demo + password: demo production: *defaults development: *defaults diff --git a/spec/support/sample_config.yml b/spec/support/sample_config.yml index b9ad29d..39caa8a 100644 --- a/spec/support/sample_config.yml +++ b/spec/support/sample_config.yml @@ -4,8 +4,8 @@ defaults: &defaults host: rabbitmq network_recovery_interval: 5 port: 5672 - username: guest - password: guest + username: demo + password: demo production: *defaults development: *defaults From 330d754e4733e329e319f5b9a570796095654629 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:33:37 -0700 Subject: [PATCH 05/25] try different default username/passwords --- lib/action_subscriber/configuration.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/action_subscriber/configuration.rb b/lib/action_subscriber/configuration.rb index 9e4b8ec..c61a025 100644 --- a/lib/action_subscriber/configuration.rb +++ b/lib/action_subscriber/configuration.rb @@ -40,7 +40,7 @@ class Configuration :host => 'rabbitmq', :hosts => [], :network_recovery_interval => NETWORK_RECOVERY_INTERVAL, - :password => "guest", + :password => "demo", :port => 5672, :prefetch => 2, :resubscribe_on_consumer_cancellation => true, @@ -51,7 +51,7 @@ class Configuration :tls_ca_certificates => [], :tls_cert => nil, :tls_key => nil, - :username => "guest", + :username => "demo", :verify_peer => true, :virtual_host => "/" } From 6c45e167fbbc5d3c525d7d1096e13e731584e78d Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:37:33 -0700 Subject: [PATCH 06/25] more --- lib/action_subscriber/rabbit_connection.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index 12be270..9ced6b2 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -29,7 +29,14 @@ def self.create_connection options[:executor_factory] = ::Proc.new do ::MarchHare::ThreadPools.fixed_of_size(options[:threadpool_size]) end + + options[:host] = "rabbitmq" + options[:password] = "guest" + options[:username] = "guest" + puts "RabbitConnection#create_connection options=#{options}" + + connection = ::MarchHare.connect(options) connection.on_blocked do |reason| on_blocked(reason) From e5c0e1402ed0f647b8d2f5ab3c1043480390f63c Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Wed, 8 Apr 2026 16:38:49 -0700 Subject: [PATCH 07/25] change defaults --- .circleci/config.yml | 6 +++--- lib/action_subscriber/rabbit_connection.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index abbb465..2152107 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,14 +14,14 @@ jobs: JRUBY_OPTS: "-J-Xmx1024m" RAILS_ENV: test # Tell your app where to find RabbitMQ (if your app uses this ENV var) - RABBITMQ_URL: "amqp://guest:guest@localhost:5672" + RABBITMQ_URL: "amqp://demo:demo@localhost:5672" # 2. The Service Container (runs in the background) - image: rabbitmq:3 # If you need the management UI for debugging, use `rabbitmq:3-management` instead # environment: - # RABBITMQ_DEFAULT_USER: guest - # RABBITMQ_DEFAULT_PASS: guest + # RABBITMQ_DEFAULT_USER: demo + # RABBITMQ_DEFAULT_PASS: demo working_directory: ~/project diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index 9ced6b2..5b9433b 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -31,8 +31,8 @@ def self.create_connection end options[:host] = "rabbitmq" - options[:password] = "guest" - options[:username] = "guest" + options[:password] = "demo" + options[:username] = "demo" puts "RabbitConnection#create_connection options=#{options}" From 88d7bec53ebd4e9933e3ae8eace4cf99be259a69 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 11:10:23 -0700 Subject: [PATCH 08/25] splat args? --- lib/action_subscriber/rabbit_connection.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index 5b9433b..977ec11 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -37,7 +37,7 @@ def self.create_connection puts "RabbitConnection#create_connection options=#{options}" - connection = ::MarchHare.connect(options) + connection = ::MarchHare.connect(**options) connection.on_blocked do |reason| on_blocked(reason) end From 76b9341bfa7bb09bcf13791a6dc6a1dcc860c333 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 14:48:51 -0700 Subject: [PATCH 09/25] remove circleci --- .circleci/config.yml | 87 -------------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 2152107..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,87 +0,0 @@ -version: 2.1 - -jobs: - build_and_test: - parameters: - docker_image: - type: string - description: "The Ruby or JRuby Docker image to test against" - - docker: - # 1. The Primary Container (where your code actually runs) - - image: << parameters.docker_image >> - environment: - JRUBY_OPTS: "-J-Xmx1024m" - RAILS_ENV: test - # Tell your app where to find RabbitMQ (if your app uses this ENV var) - RABBITMQ_URL: "amqp://demo:demo@localhost:5672" - - # 2. The Service Container (runs in the background) - - image: rabbitmq:3 - # If you need the management UI for debugging, use `rabbitmq:3-management` instead - # environment: - # RABBITMQ_DEFAULT_USER: demo - # RABBITMQ_DEFAULT_PASS: demo - - working_directory: ~/project - - steps: - - run: - name: Install System Dependencies - command: | - if [ "$(id -u)" = "0" ]; then - apt-get update && apt-get install -y build-essential git - else - sudo apt-get update && sudo apt-get install -y build-essential git - fi - - checkout - # Note: We added the docker_image parameter to the cache key - # so MRI and JRuby gems don't conflict. - - restore_cache: - keys: - - v1-gems-<< parameters.docker_image >>-{{ checksum "Gemfile.lock" }} - - v1-gems-<< parameters.docker_image >>- - - - run: - name: Install Ruby Dependencies - command: | - gem install bundler - bundle config set --local path 'vendor/bundle' - bundle install --jobs=4 --retry=3 - - - save_cache: - paths: - - ./vendor/bundle - key: v1-gems-<< parameters.docker_image >>-{{ checksum "Gemfile.lock" }} - - # Wait for RabbitMQ to be ready before running tests. - # Service containers can sometimes take a few seconds to boot up. - - run: - name: Wait for RabbitMQ - command: | - if [ "$(id -u)" = "0" ]; then - apt-get install -y netcat-openbsd - else - sudo apt-get install -y netcat-openbsd - fi - - echo "Waiting for RabbitMQ to start..." - while ! nc -z localhost 5672; do - sleep 1 - done - echo "RabbitMQ is ready!" - - - run: - name: Run Tests - command: bundle exec rspec - -workflows: - version: 2 - ruby_compatibility_matrix: - jobs: - - build_and_test: - name: test-<< matrix.docker_image >> - matrix: - parameters: - docker_image: - - "cimg/ruby:3.1" \ No newline at end of file From db0ccd0df3d48bb527931ce89156462c4dcb7e84 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 14:52:45 -0700 Subject: [PATCH 10/25] more --- .github/workflows/test.yaml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3c7b593..8e5a076 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -83,10 +83,13 @@ jobs: echo "RabbitMQ failed to start" exit 1 - - name: Run Tests - run : | - echo "$PWD" - cp ./config/action_subscriber.yml.sample ./config/action_subscriber.yml - echo "$(ls -ltr config)" + # - name: Run Tests + # run : | + # echo "$PWD" + # cp ./config/action_subscriber.yml.sample ./config/action_subscriber.yml + # echo "$(ls -ltr config)" + + # bundle exec rspec - bundle exec rspec + - name: Run Tests + run : bundle exec rspec From ab3582ef74501474f14d832dc5c2b8881a7ae29a Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 14:59:52 -0700 Subject: [PATCH 11/25] dev debug --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8e5a076..59b186c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,7 +18,7 @@ jobs: - "ruby:3.1" - "ruby:3.4" - "jruby:9.4" - - "jruby:10" + - "jruby:10.0" container: image: ${{ matrix.docker_image }} @@ -92,4 +92,4 @@ jobs: # bundle exec rspec - name: Run Tests - run : bundle exec rspec + run : JRUBY_OPTS="--dev --debug" bundle exec rspec From e2f25bed52ce1ceb02da7fdab8f771d6c5df52e4 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:03:34 -0700 Subject: [PATCH 12/25] stop skipping --- spec/lib/action_subscriber/middleware/runner_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/lib/action_subscriber/middleware/runner_spec.rb b/spec/lib/action_subscriber/middleware/runner_spec.rb index 3e85930..d546fd6 100644 --- a/spec/lib/action_subscriber/middleware/runner_spec.rb +++ b/spec/lib/action_subscriber/middleware/runner_spec.rb @@ -1,4 +1,5 @@ describe ActionSubscriber::Middleware::Runner do # TODO: Figure out at way to test this... - it "adds the router to the top of the stack" + it "adds the router to the top of the stack" do + end end From c6f52bc549a5d19cbc4d4019a37c8dccb83cdb5c Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:06:20 -0700 Subject: [PATCH 13/25] more --- .github/workflows/test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 59b186c..93b9b1b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -92,4 +92,6 @@ jobs: # bundle exec rspec - name: Run Tests - run : JRUBY_OPTS="--dev --debug" bundle exec rspec + run : | + echo $(env) + bundle exec rspec From 68201d1f022f059de3257b042e32ced6dd620a02 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:08:18 -0700 Subject: [PATCH 14/25] more --- .github/workflows/test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 93b9b1b..28c4820 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -93,5 +93,6 @@ jobs: - name: Run Tests run : | + git config --global --add safe.directory /__w/action_subscriber/action_subscriber echo $(env) bundle exec rspec From 2900ab35dc6921e688f66a84775214102a3a1a61 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:09:09 -0700 Subject: [PATCH 15/25] more --- lib/action_subscriber/rabbit_connection.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index 977ec11..da93493 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -46,6 +46,8 @@ def self.create_connection end connection else + + puts "bunny opts=#{options}" connection = ::Bunny.new(options) connection.start connection.on_blocked do |blocked_message| From 7da4d4368a61ec1a0e0e3ff729e54d1a991239b5 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:17:55 -0700 Subject: [PATCH 16/25] more --- action_subscriber.gemspec | 2 +- lib/action_subscriber/rabbit_connection.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/action_subscriber.gemspec b/action_subscriber.gemspec index cb00e6e..0eaa3d5 100644 --- a/action_subscriber.gemspec +++ b/action_subscriber.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |spec| spec.platform = "java" spec.add_dependency "march_hare", "~> 4.4" else - spec.add_dependency "bunny", ">= 1.5.0" + spec.add_dependency "bunny", ">= 2.24.0" end spec.add_dependency "concurrent-ruby" spec.add_dependency "middleware" diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index da93493..289a51d 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -47,8 +47,17 @@ def self.create_connection connection else + options[:host] = "rabbitmq" + puts "bunny opts=#{options}" connection = ::Bunny.new(options) + + if connection.host != options[:host] + raise "invalid connection -> #{connection.inspect}" + else + puts "connection -> #{connection.inspect}" + end + connection.start connection.on_blocked do |blocked_message| on_blocked(blocked_message.reason) From 097f80f6acc47b4b61ff643e8f672021c26c508b Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:23:57 -0700 Subject: [PATCH 17/25] use newer active publisher version --- action_subscriber.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action_subscriber.gemspec b/action_subscriber.gemspec index 0eaa3d5..368a097 100644 --- a/action_subscriber.gemspec +++ b/action_subscriber.gemspec @@ -32,7 +32,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 3.1.0' - spec.add_development_dependency "active_publisher", "~> 0.1.5" + spec.add_development_dependency "active_publisher", "1.6.0.pre1" spec.add_development_dependency "activerecord", ">= 6.0" spec.add_development_dependency "bundler" spec.add_development_dependency "pry-nav" From c9950821bebb7751a02e868e8879c0c6ff45eed4 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:26:41 -0700 Subject: [PATCH 18/25] add active_publisher yml sample --- .github/workflows/test.yaml | 1 + config/active_publisher.yml.sample | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 config/active_publisher.yml.sample diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 28c4820..2c8344e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -94,5 +94,6 @@ jobs: - name: Run Tests run : | git config --global --add safe.directory /__w/action_subscriber/action_subscriber + cp ./config/active_publisher.yml.sample ./config/active_publisher.yml echo $(env) bundle exec rspec diff --git a/config/active_publisher.yml.sample b/config/active_publisher.yml.sample new file mode 100644 index 0000000..c5d1431 --- /dev/null +++ b/config/active_publisher.yml.sample @@ -0,0 +1,10 @@ +default: &default + host: rabbitmq + username: demo + password: demo + +development: + <<: *default + +test: + <<: *default From 7c7791bb21960da975fdbc6903e154d01e70d7c0 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:33:32 -0700 Subject: [PATCH 19/25] more --- .github/workflows/test.yaml | 10 +--------- .gitignore | 3 +++ config/active_publisher.yml.sample | 10 ---------- lib/action_subscriber/configuration.rb | 6 +++--- lib/action_subscriber/rabbit_connection.rb | 17 ----------------- spec/spec_helper.rb | 2 ++ 6 files changed, 9 insertions(+), 39 deletions(-) delete mode 100644 config/active_publisher.yml.sample diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2c8344e..6c90cdd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -83,17 +83,9 @@ jobs: echo "RabbitMQ failed to start" exit 1 - # - name: Run Tests - # run : | - # echo "$PWD" - # cp ./config/action_subscriber.yml.sample ./config/action_subscriber.yml - # echo "$(ls -ltr config)" - - # bundle exec rspec - - name: Run Tests run : | git config --global --add safe.directory /__w/action_subscriber/action_subscriber - cp ./config/active_publisher.yml.sample ./config/active_publisher.yml + cp ./config/action_subscriber.yml.sample ./config/action_subscriber.yml echo $(env) bundle exec rspec diff --git a/.gitignore b/.gitignore index 88db647..d7c7dc3 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ Gemfile.lock .yardoc _yardoc doc/ + +config/active_publisher.yml +config/action_subscriber.yml diff --git a/config/active_publisher.yml.sample b/config/active_publisher.yml.sample deleted file mode 100644 index c5d1431..0000000 --- a/config/active_publisher.yml.sample +++ /dev/null @@ -1,10 +0,0 @@ -default: &default - host: rabbitmq - username: demo - password: demo - -development: - <<: *default - -test: - <<: *default diff --git a/lib/action_subscriber/configuration.rb b/lib/action_subscriber/configuration.rb index c61a025..060e6b6 100644 --- a/lib/action_subscriber/configuration.rb +++ b/lib/action_subscriber/configuration.rb @@ -37,10 +37,10 @@ class Configuration :connection_reaping_timeout_interval => 5, :default_exchange => 'events', :heartbeat => 5, - :host => 'rabbitmq', + :host => 'localhost', :hosts => [], :network_recovery_interval => NETWORK_RECOVERY_INTERVAL, - :password => "demo", + :password => 'guest', :port => 5672, :prefetch => 2, :resubscribe_on_consumer_cancellation => true, @@ -51,7 +51,7 @@ class Configuration :tls_ca_certificates => [], :tls_cert => nil, :tls_key => nil, - :username => "demo", + :username => 'guest', :verify_peer => true, :virtual_host => "/" } diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index 289a51d..a919bc8 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -30,13 +30,6 @@ def self.create_connection ::MarchHare::ThreadPools.fixed_of_size(options[:threadpool_size]) end - options[:host] = "rabbitmq" - options[:password] = "demo" - options[:username] = "demo" - - puts "RabbitConnection#create_connection options=#{options}" - - connection = ::MarchHare.connect(**options) connection.on_blocked do |reason| on_blocked(reason) @@ -46,18 +39,8 @@ def self.create_connection end connection else - - options[:host] = "rabbitmq" - - puts "bunny opts=#{options}" connection = ::Bunny.new(options) - if connection.host != options[:host] - raise "invalid connection -> #{connection.inspect}" - else - puts "connection -> #{connection.inspect}" - end - connection.start connection.on_blocked do |blocked_message| on_blocked(blocked_message.reason) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index cd6b9a1..8f31eb2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,6 +24,8 @@ $TESTING = true ::ActionSubscriber::Logging.initialize_logger(nil) ::ActionSubscriber.setup_default_threadpool! +# setup active publisher +::ActivePublisher::Configuration.configure_from_yaml_and_cli RSpec.configure do |config| config.mock_with :rspec do |mocks| From be70d3b1adb724a1030c8c5188e2b58360dad898 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:38:41 -0700 Subject: [PATCH 20/25] more cleanup --- spec/support/sample_config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/support/sample_config.yml b/spec/support/sample_config.yml index 39caa8a..23c7b14 100644 --- a/spec/support/sample_config.yml +++ b/spec/support/sample_config.yml @@ -1,11 +1,11 @@ --- defaults: &defaults heartbeat: 15 - host: rabbitmq + host: localhost network_recovery_interval: 5 port: 5672 - username: demo - password: demo + username: WAT + password: WAT production: *defaults development: *defaults From b073ff95e8ccdcd3e01524a89261a884593c58a1 Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:40:40 -0700 Subject: [PATCH 21/25] more --- lib/action_subscriber/rabbit_connection.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/action_subscriber/rabbit_connection.rb b/lib/action_subscriber/rabbit_connection.rb index a919bc8..0977391 100644 --- a/lib/action_subscriber/rabbit_connection.rb +++ b/lib/action_subscriber/rabbit_connection.rb @@ -30,6 +30,9 @@ def self.create_connection ::MarchHare::ThreadPools.fixed_of_size(options[:threadpool_size]) end + puts "march_hare new connection = #{options}" + + connection = ::MarchHare.connect(**options) connection.on_blocked do |reason| on_blocked(reason) @@ -41,6 +44,8 @@ def self.create_connection else connection = ::Bunny.new(options) + puts "bunny new connection = #{options}" + connection.start connection.on_blocked do |blocked_message| on_blocked(blocked_message.reason) From 176d30fcb9b1778efb443f519212cd31fa31901f Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:43:09 -0700 Subject: [PATCH 22/25] more --- spec/spec_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8f31eb2..6c2e2ef 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -26,6 +26,7 @@ ::ActionSubscriber.setup_default_threadpool! # setup active publisher ::ActivePublisher::Configuration.configure_from_yaml_and_cli +::ActionSubscriber::Configuration.configure_from_yaml_and_cli RSpec.configure do |config| config.mock_with :rspec do |mocks| From e295b5df5c3cd98afde1a2986eee342d71dd2f3f Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:47:33 -0700 Subject: [PATCH 23/25] more --- spec/integration/automatic_reconnect_spec.rb | 5 ++++- spec/integration/consumer_cancellation_spec.rb | 6 +++++- spec/spec_helper.rb | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/spec/integration/automatic_reconnect_spec.rb b/spec/integration/automatic_reconnect_spec.rb index f19cb9b..8e2efb7 100644 --- a/spec/integration/automatic_reconnect_spec.rb +++ b/spec/integration/automatic_reconnect_spec.rb @@ -12,7 +12,10 @@ def spoke default_routes_for GusSubscriber end end - let(:http_client) { RabbitMQ::HTTP::Client.new("http://127.0.0.1:15672") } + let(:rabbitmq_host) { + ENV["RABBITMQ_HOST"] || "127.0.0.1" + } + let(:http_client) { RabbitMQ::HTTP::Client.new("http://#{rabbitmq_host}:15672") } let(:subscriber) { GusSubscriber } it "reconnects when a connection drops" do diff --git a/spec/integration/consumer_cancellation_spec.rb b/spec/integration/consumer_cancellation_spec.rb index eb25aa3..09acf8d 100644 --- a/spec/integration/consumer_cancellation_spec.rb +++ b/spec/integration/consumer_cancellation_spec.rb @@ -13,7 +13,11 @@ def created default_routes_for ::YoloSubscriber end end - let(:http_client) { ::RabbitMQ::HTTP::Client.new("http://127.0.0.1:15672") } + + let(:rabbitmq_host) { + ENV["RABBITMQ_HOST"] || "127.0.0.1" + } + let(:http_client) { ::RabbitMQ::HTTP::Client.new("http://#{rabbitmq_host}:15672") } let(:subscriber) { ::YoloSubscriber } it "resubscribes on cancellation" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6c2e2ef..26aedb9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,7 +24,8 @@ $TESTING = true ::ActionSubscriber::Logging.initialize_logger(nil) ::ActionSubscriber.setup_default_threadpool! -# setup active publisher + +# load from action_subscriber.yml for both ActivePublisher and ActionSubscriber ::ActivePublisher::Configuration.configure_from_yaml_and_cli ::ActionSubscriber::Configuration.configure_from_yaml_and_cli From 4d6f6d0b456458edee8b8206887f56a8ec366f4d Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 15:55:59 -0700 Subject: [PATCH 24/25] configure user demo --- .github/workflows/test.yaml | 6 ++++++ spec/integration/automatic_reconnect_spec.rb | 6 +++--- spec/integration/consumer_cancellation_spec.rb | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6c90cdd..e45827f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -28,6 +28,7 @@ jobs: # Use the service name 'rabbitmq' as the host, not localhost RABBITMQ_URL: "amqp://demo:demo@rabbitmq:5672" RABBITMQ_HOST: rabbitmq + RABBITMQ_MANAGEMENT_URL: "http://demo:demo@rabbitmq:15672" services: rabbitmq: @@ -83,6 +84,11 @@ jobs: echo "RabbitMQ failed to start" exit 1 + - name: Configure RabbitMQ Management user "demo" + run: | + docker exec ${{ job.services.rabbitmq.id }} rabbitmqctl set_user_tags "demo" administrator + docker exec ${{ job.services.rabbitmq.id }} rabbitmqctl set_permissions -p / "demo" ".*" ".*" ".*" + - name: Run Tests run : | git config --global --add safe.directory /__w/action_subscriber/action_subscriber diff --git a/spec/integration/automatic_reconnect_spec.rb b/spec/integration/automatic_reconnect_spec.rb index 8e2efb7..d68c8ae 100644 --- a/spec/integration/automatic_reconnect_spec.rb +++ b/spec/integration/automatic_reconnect_spec.rb @@ -12,10 +12,10 @@ def spoke default_routes_for GusSubscriber end end - let(:rabbitmq_host) { - ENV["RABBITMQ_HOST"] || "127.0.0.1" + let(:rabbitmq_management_url) { + ENV["RABBITMQ_MANAGEMENT_URL"] || "http://127.0.0.1:15672" } - let(:http_client) { RabbitMQ::HTTP::Client.new("http://#{rabbitmq_host}:15672") } + let(:http_client) { RabbitMQ::HTTP::Client.new(rabbitmq_management_url) } let(:subscriber) { GusSubscriber } it "reconnects when a connection drops" do diff --git a/spec/integration/consumer_cancellation_spec.rb b/spec/integration/consumer_cancellation_spec.rb index 09acf8d..dec12ee 100644 --- a/spec/integration/consumer_cancellation_spec.rb +++ b/spec/integration/consumer_cancellation_spec.rb @@ -14,10 +14,10 @@ def created end end - let(:rabbitmq_host) { - ENV["RABBITMQ_HOST"] || "127.0.0.1" + let(:rabbitmq_management_url) { + ENV["RABBITMQ_MANAGEMENT_URL"] || "http://127.0.0.1:15672" } - let(:http_client) { ::RabbitMQ::HTTP::Client.new("http://#{rabbitmq_host}:15672") } + let(:http_client) { RabbitMQ::HTTP::Client.new(rabbitmq_management_url) } let(:subscriber) { ::YoloSubscriber } it "resubscribes on cancellation" do From c68ab6d4966ca1ce0ae294d8d6ee7dd498fc9bca Mon Sep 17 00:00:00 2001 From: John Bolliger Date: Thu, 9 Apr 2026 16:05:27 -0700 Subject: [PATCH 25/25] docker cli --- .github/workflows/test.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e45827f..1ce276c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -50,9 +50,9 @@ jobs: - name: Install System Dependencies run: | if [ "$(id -u)" = "0" ]; then - apt-get update && apt-get install -y build-essential git netcat-openbsd + apt-get update && apt-get install -y build-essential git netcat-openbsd docker-ce-cli else - sudo apt-get update && sudo apt-get install -y build-essential git netcat-openbsd + sudo apt-get update && sudo apt-get install -y build-essential git netcat-openbsd docker-ce-cli fi - name: Cache Ruby Gems @@ -72,7 +72,6 @@ jobs: - name: Wait for RabbitMQ run: | echo "Waiting for RabbitMQ to start at hostname 'rabbitmq'..." - # Fix: Use the service name 'rabbitmq' instead of 'localhost' for i in {1..30}; do if nc -z rabbitmq 5672; then echo "RabbitMQ is ready!"