@@ -92,11 +92,11 @@ private protected readonly Dictionary<Transaction, List<NpgsqlConnector>> _pendi
9292 readonly SemaphoreSlim _setupMappingsSemaphore = new ( 1 ) ;
9393
9494 readonly INpgsqlNameTranslator _defaultNameTranslator ;
95- IDisposable ? _eventSourceEvents ;
95+ readonly IDisposable ? _eventSourceEvents ;
9696
9797 internal NpgsqlDataSource (
9898 NpgsqlConnectionStringBuilder settings ,
99- NpgsqlDataSourceConfiguration dataSourceConfig )
99+ NpgsqlDataSourceConfiguration dataSourceConfig , bool reportMetrics )
100100 {
101101 Settings = settings ;
102102 ConnectionString = settings . PersistSecurityInfo
@@ -145,7 +145,21 @@ internal NpgsqlDataSource(
145145 }
146146
147147 Name = name ?? ConnectionString ;
148- MetricsReporter = new MetricsReporter ( this ) ;
148+
149+ // TODO this needs a rework, but for now we just avoid tracking multi-host data sources directly.
150+ if ( reportMetrics )
151+ {
152+ MetricsReporter = new MetricsReporter ( this ) ;
153+ if ( ! NpgsqlEventSource . Log . TryTrackDataSource ( Name , this , out _eventSourceEvents ) )
154+ _connectionLogger . LogDebug ( "NpgsqlEventSource could not start tracking a DataSource, " +
155+ "this can happen if more than one data source uses the same connection string." ) ;
156+ }
157+ else
158+ {
159+ // This is not accessed anywhere currently for multi-host data sources.
160+ // Connectors which handle the metrics always access their nonpooling/pooling data source instead.
161+ MetricsReporter = null ! ;
162+ }
149163 }
150164
151165 /// <inheritdoc cref="DbDataSource.CreateConnection" />
@@ -315,10 +329,6 @@ internal async Task Bootstrap(
315329 serializerOptions : serializerOptions ,
316330 dbTypeResolver : new ChainDbTypeResolver ( resolvers ) ) ;
317331
318- if ( ! NpgsqlEventSource . Log . TryTrackDataSource ( Name , this , out _eventSourceEvents ) )
319- _connectionLogger . LogDebug ( "NpgsqlEventSource could not start tracking a DataSource, " +
320- "this can happen if more than one data source uses the same connection string." ) ;
321-
322332 IsBootstrapped = true ;
323333 }
324334 finally
@@ -523,8 +533,11 @@ protected virtual void DisposeBase()
523533 }
524534
525535 _periodicPasswordProviderTimer ? . Dispose ( ) ;
526- MetricsReporter . Dispose ( ) ;
527- _eventSourceEvents ? . Dispose ( ) ;
536+ if ( MetricsReporter is not null )
537+ {
538+ MetricsReporter . Dispose ( ) ;
539+ _eventSourceEvents ? . Dispose ( ) ;
540+ }
528541
529542 // We do not dispose _setupMappingsSemaphore explicitly, leaving it to finalizer
530543 // Due to possible concurrent access, which might lead to deadlock
@@ -555,8 +568,11 @@ protected virtual async ValueTask DisposeAsyncBase()
555568 if ( _periodicPasswordProviderTimer is not null )
556569 await _periodicPasswordProviderTimer . DisposeAsync ( ) . ConfigureAwait ( false ) ;
557570
558- MetricsReporter . Dispose ( ) ;
559- _eventSourceEvents ? . Dispose ( ) ;
571+ if ( MetricsReporter is not null )
572+ {
573+ MetricsReporter . Dispose ( ) ;
574+ _eventSourceEvents ? . Dispose ( ) ;
575+ }
560576 // We do not dispose _setupMappingsSemaphore explicitly, leaving it to finalizer
561577 // Due to possible concurrent access, which might lead to deadlock
562578 // See issue #6115
0 commit comments