Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 109 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# This is a generated file by the `rake build_matrix:github:generate` task.
# See `build_matrix.yml` for the build matrix.
# Generate this file with `rake build_matrix:github:generate`.
# Generated job count: 194
# Generated job count: 198
---
name: Ruby gem CI
'on':
Expand Down Expand Up @@ -643,6 +643,33 @@ jobs:
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.0.gemfile
ruby_3-5-0-preview1__rails-8-1_ubuntu-latest:
name: Ruby 3.5.0-preview1 - rails-8.1
needs: ruby_3-5-0-preview1_ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.5.0-preview1
bundler-cache: true
- name: Install gem extension
run: "./script/bundler_wrapper exec rake extension:install"
- name: Print extension install report
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
file found'"
- name: Print Makefile log file
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
found'"
- name: Run tests
run: "./script/bundler_wrapper exec rake test"
env:
RAILS_ENV: test
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.1.gemfile
ruby_3-5-0-preview1__sequel_ubuntu-latest:
name: Ruby 3.5.0-preview1 - sequel
needs: ruby_3-5-0-preview1_ubuntu-latest
Expand Down Expand Up @@ -1403,6 +1430,33 @@ jobs:
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.0.gemfile
ruby_3-4-1__rails-8-1_ubuntu-latest:
name: Ruby 3.4.1 - rails-8.1
needs: ruby_3-4-1_ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4.1
bundler-cache: true
- name: Install gem extension
run: "./script/bundler_wrapper exec rake extension:install"
- name: Print extension install report
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
file found'"
- name: Print Makefile log file
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
found'"
- name: Run tests
run: "./script/bundler_wrapper exec rake test"
env:
RAILS_ENV: test
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.1.gemfile
ruby_3-4-1__sequel_ubuntu-latest:
name: Ruby 3.4.1 - sequel
needs: ruby_3-4-1_ubuntu-latest
Expand Down Expand Up @@ -2190,6 +2244,33 @@ jobs:
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.0.gemfile
ruby_3-3-4__rails-8-1_ubuntu-latest:
name: Ruby 3.3.4 - rails-8.1
needs: ruby_3-3-4_ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.4
bundler-cache: true
- name: Install gem extension
run: "./script/bundler_wrapper exec rake extension:install"
- name: Print extension install report
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
file found'"
- name: Print Makefile log file
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
found'"
- name: Run tests
run: "./script/bundler_wrapper exec rake test"
env:
RAILS_ENV: test
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.1.gemfile
ruby_3-3-4__sequel_ubuntu-latest:
name: Ruby 3.3.4 - sequel
needs: ruby_3-3-4_ubuntu-latest
Expand Down Expand Up @@ -2923,6 +3004,33 @@ jobs:
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.0.gemfile
ruby_3-2-5__rails-8-1_ubuntu-latest:
name: Ruby 3.2.5 - rails-8.1
needs: ruby_3-2-5_ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.5
bundler-cache: true
- name: Install gem extension
run: "./script/bundler_wrapper exec rake extension:install"
- name: Print extension install report
run: "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report
file found'"
- name: Print Makefile log file
run: "[ -f ext/mkmf.log ] && cat ext/mkmf.log || echo 'No ext/mkmf.log file
found'"
- name: Run tests
run: "./script/bundler_wrapper exec rake test"
env:
RAILS_ENV: test
JRUBY_OPTS: ''
COV: '1'
BUNDLE_GEMFILE: gemfiles/rails-8.1.gemfile
ruby_3-2-5__sequel_ubuntu-latest:
name: Ruby 3.2.5 - sequel
needs: ruby_3-2-5_ubuntu-latest
Expand Down
16 changes: 8 additions & 8 deletions build_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ matrix:
- "rails-7.1"
- "rails-7.2"
- "rails-8.0"
# - "rails-8.1"
- "rails-8.1"

ruby:
- ruby: "3.5.0-preview1"
Expand Down Expand Up @@ -245,13 +245,13 @@ matrix:
- "3.4.1"
- "3.3.4"
- "3.2.5"
# - gem: "rails-8.1"
# only:
# ruby:
# - "3.5.0-preview1"
# - "3.4.1"
# - "3.3.4"
# - "3.2.5"
- gem: "rails-8.1"
only:
ruby:
- "3.5.0-preview1"
- "3.4.1"
- "3.3.4"
- "3.2.5"
- gem: "sequel"
- gem: "sinatra"
- gem: "webmachine2"
Expand Down
11 changes: 11 additions & 0 deletions lib/appsignal/hooks/active_support_notifications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ def self.instrument(name, payload = {})
parent_integration_module::StartFinishHandlerIntegration,
::ActiveSupport::Notifications::Fanout::Handle
)

# Rails 8.1+ optimization: when there are no subscribers, build_handle returns
# NullHandle instead of Handle. We need to also hook into Instrumenter to
# catch these cases.
if defined?(::ActiveSupport::Notifications::Fanout::NullHandle)
instrumenter = ::ActiveSupport::Notifications::Instrumenter
install_module(
parent_integration_module::NullHandleAwareInstrumentIntegration,
instrumenter
)
end
else
instrumenter = ::ActiveSupport::Notifications::Instrumenter

Expand Down
35 changes: 35 additions & 0 deletions lib/appsignal/integrations/active_support_notifications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,41 @@ def finish_with_state(listeners_state, name, payload = {})
super
end
end

# Rails 8.1+ introduced NullHandle as a performance optimization.
# This integration only instruments when NullHandle is being used
# (i.e., when there are no other subscribers).
module NullHandleAwareInstrumentIntegration
def instrument(name, payload = {}, &block)
handle = build_handle(name, payload)

# Only instrument if NullHandle is being used.
# If Handle is being used, StartFinishHandlerIntegration will handle it.
if defined?(::ActiveSupport::Notifications::Fanout::NullHandle) &&
handle == ::ActiveSupport::Notifications::Fanout::NullHandle
instrument_this = name[0] != ActiveSupportNotificationsIntegration::BANG

Appsignal::Transaction.current.start_event if instrument_this

begin
super
ensure
if instrument_this
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
Appsignal::Transaction.current.finish_event(
name.to_s,
title,
body,
body_format
)
end
end
else
# Regular Handle case: let StartFinishHandlerIntegration handle it
super
end
end
end
end
end
end
24 changes: 13 additions & 11 deletions spec/lib/appsignal/hooks/active_support_notifications_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,24 @@

it_behaves_like "activesupport instrument override"

if defined?(::ActiveSupport::Notifications::Fanout::Handle)
require_relative "active_support_notifications/start_finish_shared_examples"
unless defined?(::ActiveSupport::Notifications::Fanout::NullHandle)
if defined?(::ActiveSupport::Notifications::Fanout::Handle)
require_relative "active_support_notifications/start_finish_shared_examples"

it_behaves_like "activesupport start finish override"
end
it_behaves_like "activesupport start finish override"
end

if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:start)
require_relative "active_support_notifications/start_finish_shared_examples"
if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:start)
require_relative "active_support_notifications/start_finish_shared_examples"

it_behaves_like "activesupport start finish override"
end
it_behaves_like "activesupport start finish override"
end

if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:finish_with_state)
require_relative "active_support_notifications/finish_with_state_shared_examples"
if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:finish_with_state)
require_relative "active_support_notifications/finish_with_state_shared_examples"

it_behaves_like "activesupport finish_with_state override"
it_behaves_like "activesupport finish_with_state override"
end
end
else
describe "#dependencies_present?" do
Expand Down
Loading