Skip to content

Conversation

@xuan-cao-swi
Copy link
Contributor

Description

Test (if applicable)

@xuan-cao-swi xuan-cao-swi marked this pull request as ready for review December 8, 2025 16:54
@xuan-cao-swi xuan-cao-swi requested review from a team as code owners December 8, 2025 16:54
@xuan-cao-swi xuan-cao-swi requested a review from Copilot January 5, 2026 17:09
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the token bucket implementation to use a time-based calculation approach instead of a timer-thread model. The main change eliminates the background thread that periodically replenished tokens, replacing it with on-demand calculations based on elapsed time since last usage. This improves thread safety and simplifies the implementation.

Key Changes:

  • Replaced timer-based token replenishment with time-elapsed calculations
  • Changed rate parameter from "tokens per interval" to "tokens per second"
  • Added proper thread safety with mutex locks for all token bucket operations
  • Deprecated sample_rate and sampling_rate configuration options

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
lib/solarwinds_apm/sampling/token_bucket.rb Complete refactoring to use time-based token calculation, removed timer thread, added mutex locking for thread safety
lib/solarwinds_apm/sampling/oboe_sampler.rb Removed timer start calls and reorganized mutex synchronization in update_settings and get_settings methods
lib/solarwinds_apm/config.rb Deprecated sample_rate and sampling_rate configuration options with simplified warning messages
test/sampling/token_bucket_test.rb Updated tests to reflect new token bucket behavior with time-based replenishment and added thread safety tests
test/sampling/oboe_sampler_test.rb Changed bucket initialization from TokenBucket objects to hash-based settings
test/Dockerfile Updated Ruby version from 3.1.0 to 3.2.6 and removed SWIG installation

@settings = {}
return
@settings_mutex.synchronize do
return if @settings.empty?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking with copilot help on the question of early returns from a mutex synchronized block, whether that would release the lock. Seems yes (at least for MRI) but also seems break could be better. It also raised the question that the early return here, and later if settings expired in line 333, means the return value for get_settings could be nil and the caller needs to properly handle that--does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they will return nil and be handled by unless sample_state.settings

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm but i see before that line there's also https://github.com/solarwinds/apm-ruby/blob/NH-124861/lib/solarwinds_apm/sampling/oboe_sampler.rb#L77

if sample_state.headers['X-Trace-Options']

which would throw an error if sample_state is nil?

Copy link
Contributor Author

@xuan-cao-swi xuan-cao-swi Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think sample_state will be nil. It will always create the struct from SampleState.new after entering should_sample?

Copy link
Contributor

@cheempz cheempz Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG i can't read, yes you're right. But now also seeing https://github.com/solarwinds/apm-ruby/blob/7.1.0/lib/solarwinds_apm/sampling/oboe_sampler.rb#L133

elsif sample_state.settings[:flags].anybits?(Flags::SAMPLE_START)

which would access a possibly nill settings? guess my point is, is there some way to ensure the sample_state.settings is a hash such that callers don't have to worry about it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the sample_state.settings is nil, then it will return at L122.

although I can make it empty hash if it become to nil (from L70)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see.

@xuan-cao-swi xuan-cao-swi requested a review from cheempz January 14, 2026 20:10
Copy link
Contributor

@cheempz cheempz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revisit, one remaining question @xuan-cao-swi

@settings = {}
return
@settings_mutex.synchronize do
return if @settings.empty?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm but i see before that line there's also https://github.com/solarwinds/apm-ruby/blob/NH-124861/lib/solarwinds_apm/sampling/oboe_sampler.rb#L77

if sample_state.headers['X-Trace-Options']

which would throw an error if sample_state is nil?

Copy link
Contributor

@cheempz cheempz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@xuan-cao-swi xuan-cao-swi merged commit 4eeed54 into main Jan 16, 2026
14 checks passed
@xuan-cao-swi xuan-cao-swi deleted the NH-124861 branch January 16, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants