Skip to content

Commit

Permalink
Ruby 3.2 updates
Browse files Browse the repository at this point in the history
* Start using Ruby 3.2.0-preview2 for CI
* Support Ruby 3.2's two separate VM stats,
  `:constant_cache_invalidations` and `:constant_cache_misses`.

Prior to Ruby 3.2, Ruby offered a `:global_constant_state` VM stat that
the New Relic Ruby agent used to report on constant cache invalidations.

Ruby 3.2 offers improved statistics for constants and has replaced
`:global_constant_state` with 2 new attributes,
`:constant_cache_invalidations` and `:constant_cache_misses`. The New
Relic Ruby agent will use `:constant_cache_invalidations` for its
existing reporting of invalidations and will also start to report on
constant cache misses when Ruby 3.2+ is present.

Resolves #1059
  • Loading branch information
fallwith committed Sep 15, 2022
1 parent c91b9ce commit 65292ef
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 18 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci_cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1, jruby-9.3.8.0]
ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2, jruby-9.3.8.0]

steps:
- name: Configure git
Expand Down Expand Up @@ -83,7 +83,7 @@ jobs:
"3.1.2": {
"rails": "norails,rails61,rails70,railsedge"
},
"3.2.0-preview1": {
"3.2.0-preview2": {
"rails": "norails,rails61,rails70,railsedge"
},
"jruby-9.3.8.0": {
Expand Down Expand Up @@ -177,7 +177,7 @@ jobs:
fail-fast: false
matrix:
multiverse: [agent, background, background_2, database, frameworks, httpclients, httpclients_2, rails, rest]
ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1]
ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2]
steps:
- name: Configure git
run: 'git config --global init.defaultBranch main'
Expand Down Expand Up @@ -240,7 +240,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby-version: [2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1]
ruby-version: [2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2]
steps:
- name: Configure git
run: 'git config --global init.defaultBranch main'
Expand Down
2 changes: 2 additions & 0 deletions lib/new_relic/agent/samplers/vm_sampler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class VMSampler < Sampler
MINOR_GC_METRIC = 'RubyVM/GC/minor_gc_count'.freeze
METHOD_INVALIDATIONS_METRIC = 'RubyVM/CacheInvalidations/method'.freeze
CONSTANT_INVALIDATIONS_METRIC = 'RubyVM/CacheInvalidations/constant'.freeze
CONSTANT_MISSES_METRIC = 'RubyVM/CacheMisses/constant'.freeze

attr_reader :transaction_count

Expand Down Expand Up @@ -115,6 +116,7 @@ def poll
record_delta(snap, :minor_gc_count, MINOR_GC_METRIC, tcount)
record_delta(snap, :method_cache_invalidations, METHOD_INVALIDATIONS_METRIC, tcount)
record_delta(snap, :constant_cache_invalidations, CONSTANT_INVALIDATIONS_METRIC, tcount)
record_delta(snap, :constant_cache_misses, CONSTANT_MISSES_METRIC, tcount)
record_heap_live_metric(snap)
record_heap_free_metric(snap)
record_thread_count_metric(snap)
Expand Down
20 changes: 11 additions & 9 deletions lib/new_relic/agent/vm/mri_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ def gather_ruby_vm_stats(snap)
if supports?(:constant_cache_invalidations)
snap.constant_cache_invalidations = gather_constant_cache_invalidations
end

if supports?(:constant_cache_misses)
snap.constant_cache_misses = gather_constant_cache_misses
end
end

def gather_constant_cache_invalidations
# Ruby >= 3.2 uses :constant_cache
# see: https://github.com/ruby/ruby/pull/5433 and https://bugs.ruby-lang.org/issues/18589
# TODO: now that 3.2+ provides more granual cache invalidation data, should we report it instead of summing?
if RUBY_VERSION >= '3.2.0'
RubyVM.stat[:constant_cache].values.sum
# Ruby < 3.2 uses :global_constant_state
else
RubyVM.stat[:global_constant_state]
end
RubyVM.stat[RUBY_VERSION >= '3.2.0' ? :constant_cache_invalidations : :global_constant_state]
end

def gather_constant_cache_misses
RubyVM.stat[:constant_cache_misses]
end

def gather_thread_stats(snap)
Expand All @@ -84,6 +84,8 @@ def supports?(key)
RUBY_VERSION >= '2.1.0' && RUBY_VERSION < '3.0.0'
when :constant_cache_invalidations
RUBY_VERSION >= '2.1.0'
when :constant_cache_misses
RUBY_VERSION >= '3.2.0'
else
false
end
Expand Down
2 changes: 1 addition & 1 deletion lib/new_relic/agent/vm/snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Snapshot
attr_accessor :gc_total_time, :gc_runs, :major_gc_count, :minor_gc_count,
:total_allocated_object, :heap_live, :heap_free,
:method_cache_invalidations, :constant_cache_invalidations,
:thread_count, :taken_at
:constant_cache_misses, :thread_count, :taken_at

def initialize
@taken_at = Process.clock_gettime(Process::CLOCK_REALTIME)
Expand Down
25 changes: 21 additions & 4 deletions test/new_relic/agent/samplers/vm_sampler_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def setup
:heap_live => 0,
:heap_free => 0,
:method_cache_invalidations => 0,
:constant_cache_invalidations => 0
:constant_cache_invalidations => 0,
:constant_cache_misses => 0
)
@sampler = VMSampler.new
@sampler.setup_events(NewRelic::Agent.instance.events)
Expand Down Expand Up @@ -128,7 +129,8 @@ def test_poll_records_heap_usage_metrics
def test_poll_records_vm_cache_invalidations
stub_snapshot(
:method_cache_invalidations => 100,
:constant_cache_invalidations => 200
:constant_cache_invalidations => 200,
:constant_cache_misses => 175
)
generate_transactions(50)
@sampler.poll
Expand All @@ -141,6 +143,10 @@ def test_poll_records_vm_cache_invalidations
'RubyVM/CacheInvalidations/constant' => {
:call_count => 50, # number of transactions
:total_call_time => 200 # number of constant cache invalidations
},
'RubyVM/CacheMisses/constant' => {
:call_count => 50, # number of transactions
:total_call_time => 175 # number of constant cache misses
}
)
end
Expand Down Expand Up @@ -186,7 +192,8 @@ def test_poll_records_deltas_not_cumulative_values
:major_gc_count => 10,
:minor_gc_count => 10,
:method_cache_invalidations => 10,
:constant_cache_invalidations => 10
:constant_cache_invalidations => 10,
:constant_cache_misses => 10
)
@sampler.poll

Expand All @@ -209,6 +216,9 @@ def test_poll_records_deltas_not_cumulative_values
},
'RubyVM/CacheInvalidations/constant' => {
:total_call_time => 10
},
'RubyVM/CacheMisses/constant' => {
:total_call_time => 10
}
}

Expand All @@ -223,7 +233,8 @@ def test_poll_records_deltas_not_cumulative_values
:major_gc_count => 20,
:minor_gc_count => 20,
:method_cache_invalidations => 20,
:constant_cache_invalidations => 20
:constant_cache_invalidations => 20,
:constant_cache_misses => 20
)
@sampler.poll

Expand All @@ -242,6 +253,7 @@ def test_poll_aggregates_multiple_polls
:minor_gc_count => 10,
:method_cache_invalidations => 10,
:constant_cache_invalidations => 10,
:constant_cache_misses => 10,
:taken_at => 10
)
generate_transactions(10)
Expand All @@ -255,6 +267,7 @@ def test_poll_aggregates_multiple_polls
:minor_gc_count => 20,
:method_cache_invalidations => 20,
:constant_cache_invalidations => 20,
:constant_cache_misses => 20,
:taken_at => 20
)
generate_transactions(10)
Expand Down Expand Up @@ -286,6 +299,10 @@ def test_poll_aggregates_multiple_polls
'RubyVM/CacheInvalidations/constant' => {
:call_count => 20,
:total_call_time => 20
},
'RubyVM/CacheMisses/constant' => {
:call_count => 20,
:total_call_time => 20
}
)
end
Expand Down
1 change: 1 addition & 0 deletions test/new_relic/agent/vm_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def test_gets_snapshot
:heap_free,
:method_cache_invalidations,
:constant_cache_invalidations,
:constant_cache_misses,
:thread_count
]

Expand Down

0 comments on commit 65292ef

Please sign in to comment.