Skip to content

Commit 73a7f95

Browse files
committed
Update DiscoveryService
1 parent 153f5fe commit 73a7f95

File tree

6 files changed

+71
-23
lines changed

6 files changed

+71
-23
lines changed

tracer/src/Datadog.Trace.Tools.Runner/Utils.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,9 @@ public static async Task<AgentConfiguration> CheckAgentConnectionAsync(string ag
417417

418418
var settings = new TracerSettings(configurationSource, new ConfigurationTelemetry(), new OverrideErrorLog());
419419

420-
Log.Debug("Creating DiscoveryService for: {AgentUri}", settings.Exporter.AgentUri);
421-
var discoveryService = DiscoveryService.Create(
422-
settings.Exporter,
420+
Log.Debug("Creating DiscoveryService for: {AgentUri}", settings.Manager.InitialExporterSettings.AgentUri);
421+
var discoveryService = DiscoveryService.CreateUnmanaged(
422+
settings.Manager.InitialExporterSettings,
423423
tcpTimeout: TimeSpan.FromSeconds(5),
424424
initialRetryDelayMs: 200,
425425
maxRetryDelayMs: 1000,
@@ -433,7 +433,7 @@ public static async Task<AgentConfiguration> CheckAgentConnectionAsync(string ag
433433
using (cts.Token.Register(
434434
() =>
435435
{
436-
WriteError($"Error connecting to the Datadog Agent at {settings.Exporter.AgentUri}.");
436+
WriteError($"Error connecting to the Datadog Agent at {settings.Manager.InitialExporterSettings.AgentUri}.");
437437
tcs.TrySetResult(null);
438438
}))
439439
{

tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,35 @@ internal class DiscoveryService : IDiscoveryService
3232
private const string SupportedTracerFlareEndpoint = "tracer_flare/v1";
3333

3434
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor<DiscoveryService>();
35-
private readonly IApiRequestFactory _apiRequestFactory;
3635
private readonly int _initialRetryDelayMs;
3736
private readonly int _maxRetryDelayMs;
3837
private readonly int _recheckIntervalMs;
3938
private readonly TaskCompletionSource<bool> _processExit = new();
4039
private readonly List<Action<AgentConfiguration>> _agentChangeCallbacks = new();
4140
private readonly object _lock = new();
4241
private readonly Task _discoveryTask;
42+
private IApiRequestFactory _apiRequestFactory;
4343
private AgentConfiguration? _configuration;
4444

45+
public DiscoveryService(
46+
TracerSettings.SettingsManager settings,
47+
TimeSpan tcpTimeout,
48+
int initialRetryDelayMs,
49+
int maxRetryDelayMs,
50+
int recheckIntervalMs)
51+
: this(CreateApiRequestFactory(settings.InitialExporterSettings, tcpTimeout), initialRetryDelayMs, maxRetryDelayMs, recheckIntervalMs)
52+
{
53+
// Create as a "managed" service that can update the request factory
54+
settings.SubscribeToChanges(changes =>
55+
{
56+
if (changes.UpdatedExporter is { } exporter)
57+
{
58+
var newFactory = CreateApiRequestFactory(exporter, tcpTimeout);
59+
Interlocked.Exchange(ref _apiRequestFactory!, newFactory);
60+
}
61+
});
62+
}
63+
4564
/// <summary>
4665
/// Initializes a new instance of the <see cref="DiscoveryService"/> class.
4766
/// Public for testing purposes
@@ -79,28 +98,39 @@ public DiscoveryService(
7998
SupportedTracerFlareEndpoint,
8099
};
81100

82-
public static DiscoveryService Create(ExporterSettings exporterSettings)
83-
=> Create(
101+
/// <summary>
102+
/// Create a <see cref="DiscoveryService"/> instance that responds to runtime changes in settings
103+
/// </summary>
104+
public static DiscoveryService CreateManaged(TracerSettings settings)
105+
=> new(
106+
settings.Manager,
107+
tcpTimeout: TimeSpan.FromSeconds(15),
108+
initialRetryDelayMs: 500,
109+
maxRetryDelayMs: 5_000,
110+
recheckIntervalMs: 30_000);
111+
112+
/// <summary>
113+
/// Create a <see cref="DiscoveryService"/> instance that does _not_ respond to runtime changes in settings
114+
/// </summary>
115+
public static DiscoveryService CreateUnmanaged(ExporterSettings exporterSettings)
116+
=> CreateUnmanaged(
84117
exporterSettings,
85118
tcpTimeout: TimeSpan.FromSeconds(15),
86119
initialRetryDelayMs: 500,
87120
maxRetryDelayMs: 5_000,
88121
recheckIntervalMs: 30_000);
89122

90-
public static DiscoveryService Create(
123+
/// <summary>
124+
/// Create a <see cref="DiscoveryService"/> instance that does _not_ respond to runtime changes in settings
125+
/// </summary>
126+
public static DiscoveryService CreateUnmanaged(
91127
ExporterSettings exporterSettings,
92128
TimeSpan tcpTimeout,
93129
int initialRetryDelayMs,
94130
int maxRetryDelayMs,
95131
int recheckIntervalMs)
96132
=> new(
97-
AgentTransportStrategy.Get(
98-
exporterSettings,
99-
productName: "discovery",
100-
tcpTimeout: tcpTimeout,
101-
AgentHttpHeaderNames.MinimalHeaders,
102-
() => new MinimalAgentHeaderHelper(),
103-
uri => uri),
133+
CreateApiRequestFactory(exporterSettings, tcpTimeout),
104134
initialRetryDelayMs,
105135
maxRetryDelayMs,
106136
recheckIntervalMs);
@@ -166,15 +196,24 @@ private void NotifySubscribers(AgentConfiguration newConfig)
166196

167197
private async Task FetchConfigurationLoopAsync()
168198
{
169-
var uri = _apiRequestFactory.GetEndpoint("info");
199+
var requestFactory = _apiRequestFactory;
200+
var uri = requestFactory.GetEndpoint("info");
170201

171202
int? sleepDuration = null;
172203

173204
while (!_processExit.Task.IsCompleted)
174205
{
175206
try
176207
{
177-
var api = _apiRequestFactory.Create(uri);
208+
// If the exporter settings have been updated, refresh the endpoint
209+
var updatedFactory = Volatile.Read(ref _apiRequestFactory);
210+
if (requestFactory != updatedFactory)
211+
{
212+
requestFactory = updatedFactory;
213+
uri = requestFactory.GetEndpoint("info");
214+
}
215+
216+
var api = requestFactory.Create(uri);
178217

179218
using var response = await api.GetAsync().ConfigureAwait(false);
180219
if (response.StatusCode is >= 200 and < 300)
@@ -328,5 +367,14 @@ public Task DisposeAsync()
328367

329368
return _discoveryTask;
330369
}
370+
371+
private static IApiRequestFactory CreateApiRequestFactory(ExporterSettings exporterSettings, TimeSpan tcpTimeout)
372+
=> AgentTransportStrategy.Get(
373+
exporterSettings,
374+
productName: "discovery",
375+
tcpTimeout: tcpTimeout,
376+
AgentHttpHeaderNames.MinimalHeaders,
377+
() => new MinimalAgentHeaderHelper(),
378+
uri => uri);
331379
}
332380
}

tracer/src/Datadog.Trace/Ci/TestOptimization.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public void Initialize()
239239
// In case we are running using the agent, check if the event platform proxy is supported.
240240
TracerManagement = new TestOptimizationTracerManagement(
241241
settings: Settings,
242-
getDiscoveryServiceFunc: static s => DiscoveryService.Create(
242+
getDiscoveryServiceFunc: static s => DiscoveryService.CreateUnmanaged(
243243
s.TracerSettings.Manager.InitialExporterSettings,
244244
tcpTimeout: TimeSpan.FromSeconds(5),
245245
initialRetryDelayMs: 100,

tracer/src/Datadog.Trace/TracerManagerFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,6 @@ protected virtual IAgentWriter GetAgentWriter(TracerSettings settings, IDogStats
283283
}
284284

285285
protected virtual IDiscoveryService GetDiscoveryService(TracerSettings settings)
286-
=> DiscoveryService.Create(settings.Exporter);
286+
=> DiscoveryService.CreateManaged(settings);
287287
}
288288
}

tracer/test/Datadog.Trace.IntegrationTests/LibDatadog/TraceExporterTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public async Task SendsTracesUsingDataPipeline(TestTransports transport)
7575

7676
var sampleRateResponses = new ConcurrentQueue<Dictionary<string, float>>();
7777

78-
var discovery = DiscoveryService.Create(tracerSettings.Exporter);
78+
var discovery = DiscoveryService.CreateUnmanaged(tracerSettings.Manager.InitialExporterSettings);
7979
var statsd = new NoOpStatsd();
8080

8181
// We have to replace the agent writer so that we can intercept the sample rate responses

tracer/test/Datadog.Trace.IntegrationTests/StatsTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public async Task SendsStatsWithProcessing_Normalizer()
5858
{ ConfigurationKeys.TraceDataPipelineEnabled, "false" },
5959
});
6060

61-
var discovery = DiscoveryService.Create(settings.Exporter);
61+
var discovery = DiscoveryService.CreateUnmanaged(settings.Manager.InitialExporterSettings);
6262
// Note: we are explicitly _not_ using a using here, as we dispose it ourselves manually at a specific point
6363
// and this was easiest to retrofit without changing the test structure too much.
6464
var tracer = TracerHelper.Create(settings, agentWriter: null, sampler: null, scopeManager: null, statsd: null, discoveryService: discovery);
@@ -205,7 +205,7 @@ public async Task SendsStatsWithProcessing_Obfuscator()
205205
{ ConfigurationKeys.TraceDataPipelineEnabled, "false" },
206206
});
207207

208-
var discovery = DiscoveryService.Create(settings.Exporter);
208+
var discovery = DiscoveryService.CreateUnmanaged(settings.Manager.InitialExporterSettings);
209209
// Note: we are explicitly _not_ using a using here, as we dispose it ourselves manually at a specific point
210210
// and this was easiest to retrofit without changing the test structure too much.
211211
var tracer = TracerHelper.Create(settings, agentWriter: null, sampler: null, scopeManager: null, statsd: null, discoveryService: discovery);
@@ -366,7 +366,7 @@ private async Task SendStatsHelper(bool statsComputationEnabled, bool expectStat
366366
{ ConfigurationKeys.TraceDataPipelineEnabled, "false" },
367367
}));
368368

369-
var discovery = DiscoveryService.Create(settings.Exporter);
369+
var discovery = DiscoveryService.CreateUnmanaged(settings.Manager.InitialExporterSettings);
370370
// Note: we are explicitly _not_ using a using here, as we dispose it ourselves manually at a specific point
371371
// and this was easiest to retrofit without changing the test structure too much.
372372
var tracer = TracerHelper.Create(settings, agentWriter: null, sampler: null, scopeManager: null, statsd: null, discoveryService: discovery);

0 commit comments

Comments
 (0)