@@ -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}
0 commit comments