Skip to content

Conversation

marcotc
Copy link
Member

@marcotc marcotc commented Aug 28, 2025

Fixes #3465

Async query execution, introduced in Rails 7.0.0 and expanded in Rails 7.1.0, now correctly parents the async spans to the context where the query resolution happens.
This context is the place where the results from the async query were consumed. For example: async_relation = Model.load_async schedules the async query, but the query span is only attached to the active trace at relation.load time). This only affects parenting, as the execution time of the async span is always accurate.

The active trace, started in a thread, will now see spans from a background async thread attached to it.

Change log entry
Yes. Add support for ActiveRecord async queries

Additional Notes:

How to test the change?

@github-actions github-actions bot added integrations Involves tracing integrations tracing labels Aug 28, 2025
Copy link

datadog-official bot commented Aug 28, 2025

⚠️ Tests

⚠️ Warnings

❄️ 5 New flaky tests detected

ActiveRecord async instrumentation with adapter supporting background execution parents the database span to the calling context from rspec (Datadog)
Database configuration should have already been resolved

Failure/Error: raise RSpec::Expectations::ExpectationNotMetError, 'Database configuration should have already been resolved'
  Database configuration should have already been resolved
./spec/datadog/tracing/contrib/active_record/instantiation_spec.rb:76:in \`block (5 levels) in <top (required)>'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:279:in \`block in build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`reverse_each'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:257:in \`build_db_config_from_raw_config'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:181:in \`resolve'
...
Datadog::Tracing::Contrib::ActiveRecord::Configuration::Resolver#add with a hash matcher resolves to a normalized hash matcher from rspec (Datadog) (✨ Fix with BitsAI)
Database configuration should have already been resolved

Failure/Error: raise RSpec::Expectations::ExpectationNotMetError, 'Database configuration should have already been resolved'
  Database configuration should have already been resolved
./spec/datadog/tracing/contrib/active_record/instantiation_spec.rb:76:in \`block (5 levels) in <top (required)>'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:279:in \`block in build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`reverse_each'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:257:in \`build_db_config_from_raw_config'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:181:in \`resolve'
...
Datadog::Tracing::Contrib::ActiveRecord::Configuration::Resolver#add with a symbol matcher with a valid ActiveRecord database resolves to a normalized hash matcher from rspec (Datadog)
Database configuration should have already been resolved

Failure/Error: raise RSpec::Expectations::ExpectationNotMetError, 'Database configuration should have already been resolved'
  Database configuration should have already been resolved
./spec/datadog/tracing/contrib/active_record/instantiation_spec.rb:76:in \`block (5 levels) in <top (required)>'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:279:in \`block in build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`reverse_each'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:278:in \`build_db_config_from_hash'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:257:in \`build_db_config_from_raw_config'
/usr/local/bundle/gems/activerecord-7.2.2.2/lib/active_record/database_configurations.rb:208:in \`block in build_configs'
...
View all

🧪 5 Tests failed

ActiveRecord instantiation instrumentation when a model is instantiated and service_name is not set is expected to equal 2 from rspec (Datadog) (✨ Fix with BitsAI)
expected #<Integer:5> => 2
     got #<Integer:7> => 3

Compared using equal?, which compares object identity,
but expected and actual are not the same object. Use
\`expect(actual).to eq(expected)\` if you don't care about
object identity in this example.

Failure/Error: expect(spans.length).to be(2)

...
ActiveRecord instantiation instrumentation when a model is instantiated and service_name is set is expected to equal 2 from rspec (Datadog) (✨ Fix with BitsAI)
expected #<Integer:5> => 2
     got #<Integer:7> => 3

Compared using equal?, which compares object identity,
but expected and actual are not the same object. Use
\`expect(actual).to eq(expected)\` if you don't care about
object identity in this example.

Failure/Error: expect(spans.length).to be(2)

...
ActiveRecord instantiation instrumentation when a model is instantiated behaves like analytics for integration when configured by configuration options and explicitly disabled and global flag is explicitly disabled behaves like sample rate value isn't set is expected to equal 2 from rspec (Datadog) (✨ Fix with BitsAI)
expected #<Integer:5> => 2
     got #<Integer:7> => 3

Compared using equal?, which compares object identity,
but expected and actual are not the same object. Use
\`expect(actual).to eq(expected)\` if you don't care about
object identity in this example.

Failure/Error: expect(spans.length).to be(2)

...
View all
This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 23b97c5 | Docs | Was this helpful? Give us feedback!

@pr-commenter
Copy link

pr-commenter bot commented Sep 3, 2025

Benchmarks

Benchmark execution time: 2025-09-23 00:17:23

Comparing candidate commit 23b97c5 in PR branch fix-load-async with baseline commit 4da2fc1 in branch master.

Found 0 performance improvements and 3 performance regressions! Performance is the same for 41 metrics, 2 unstable metrics.

scenario:line instrumentation - targeted

  • 🟥 throughput [-8714.974op/s; -8058.424op/s] or [-5.578%; -5.158%]

scenario:method instrumentation

  • 🟥 throughput [-9806.889op/s; -9240.113op/s] or [-5.464%; -5.148%]

scenario:tracing - Propagation - Datadog

  • 🟥 throughput [-2854.535op/s; -2764.425op/s] or [-8.855%; -8.576%]

marcotc and others added 13 commits September 22, 2025 14:50
**What does this PR do?**
Adds support for Rails load_async feature by implementing the publish method and
enhancing the ActiveSupport notifications subscription system with proper callback
handling and error management.

**Motivation:**
Rails load_async feature requires support for the publish method in ActiveSupport
notifications to handle asynchronous event processing. The existing subscription
system needed enhancements to properly support this Rails feature.

**Change log entry**
Added support for Rails load_async feature in ActiveSupport notifications subscription

**Additional Notes:**
- Implements publish method for complete event lifecycle handling
- Adds robust error handling for callbacks and handlers
- Includes comprehensive test coverage (38 examples, 0 failures)
- Ensures system continues functioning when individual callbacks fail

**How to test the change?**
Run: bundle exec rspec spec/datadog/tracing/contrib/active_support/notifications/subscription_spec.rb
Tests verify load_async functionality including:
- publish method event lifecycle
- Handler and Callbacks error handling
- Integration with Rails async event processing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrations Involves tracing integrations tracing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Active record async queries are considered separate traces
1 participant