Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract components from configuration #996

Merged
merged 4 commits into from
Apr 9, 2020

Conversation

delner
Copy link
Contributor

@delner delner commented Apr 8, 2020

Currently our configuration settings and tracer components (Tracer, RuntimeMetrics, etc) are mutable which makes state management cumbersome and can result in some undesirable side effects when reconfigured.

In this pull request, we'd like to address some of these issues by moving towards an immutable configuration model, where tracer components are not mutated, but recreated. This should make state management of tracer components simpler and consistent.

In practice:

  1. Users configure the application with Datadog.configure { |c| #... } and apply the settings they desire, which mutates the Datadog.configuration settings object.
  2. When Datadog.configure block completes, it creates a Components object from the settings, which contains all the major components used by the tracer (e.g. Tracer, HealthMetrics, etc.)
  3. The old Components are torn down (e.g. clean up threads, etc), then replaced by the new Components instance.
  4. Trace components become available through helper methods e.g. Datadog.tracer for use.

To accomplish this, it requires moving a lot of parts around, including that used to be inside Datadog::Configuration::Settings to Datadog::Configuration::Components, including:

  • Tracer, RuntimeMetrics, HealthMetrics from Datadog::Configuration::Settings to Datadog::Configuration::Components
  • Changing a number of old configuration settings to new ones (these will be deprecated in the future):
    • c.tracer { enabled: true, ... } --> c.tracer.enabled = true and more.
    • c.runtime_metrics { enabled: true, ... } --> c.runtime_metrics.enabled = true and more.
    • c.analytics_enabled = true --> c.analytics.enabled = true
  • Backfilling a lot of configuration tests

@delner delner added core Involves Datadog core libraries dev/refactor Involves refactoring existing components labels Apr 8, 2020
@delner delner added this to the 0.35.0 milestone Apr 8, 2020
@delner delner self-assigned this Apr 8, 2020
@delner
Copy link
Contributor Author

delner commented Apr 8, 2020

I want to double check that Tracer#shutdown! still applies correctly when exit is invoked, but then this should be ready for review.

@delner delner marked this pull request as ready for review April 8, 2020 13:42
@delner delner requested a review from a team April 8, 2020 13:42
else
Datadog::ContextFlush::Finished.new
end
if options.key?(:partial_flush)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was a bug where calling #configure would turn off partial flushing if it had previously been configured, but the option wasn't specified on the second call.

@@ -355,10 +358,10 @@ def configure_writer(options = {})
sampler = options.fetch(:sampler, nil)
priority_sampling = options.fetch(:priority_sampling, nil)
writer = options.fetch(:writer, nil)
transport_options = options.fetch(:transport_options, {})
transport_options = options.fetch(:transport_options, {}).dup
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was a bug where building options for a new writer would mutate the provided Hash by reference, causing unwanted side effects.

@@ -6,6 +6,178 @@
RSpec.describe Datadog::Configuration::Settings do
subject(:settings) { described_class.new }

describe '#analytics' do
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Backfilled a lot of tests for configuration settings in this file that was previously missing.

after do
Datadog::Logger.debug_logging = false
context 'when modified' do
it 'does not modify the default by reference' do
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was an issue when option :writer_options, default: {} was defined, because a user could errantly modify the default by reference.

@@ -9,6 +10,140 @@

describe '#configure' do
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of these tests are "integration-like" in the sense that they apply some high level settings and consequently run through other components like Configuration::Settings and Configuration::Components and assert on the stateful outcome of those classes.

Might want to extract this kind of behavioral test elsewhere, but put it in here for now, to ensure basic usage works as intended.

Copy link
Member

@marcotc marcotc left a comment

Choose a reason for hiding this comment

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

Very nice improvements, looks great overall!
There are only few questions I asked in my comments below.

lib/ddtrace/configuration.rb Show resolved Hide resolved
lib/ddtrace/configuration.rb Show resolved Hide resolved
Copy link
Member

@marcotc marcotc left a comment

Choose a reason for hiding this comment

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

Awesome work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Involves Datadog core libraries dev/refactor Involves refactoring existing components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants