Skip to content

Commit c451b28

Browse files
neyromantAndrey.Kudashkin
andauthored
Fix event counters around similar connection strings (#3485)
Fixes #3480 Co-authored-by: Andrey.Kudashkin <andrey.kudashkin@russianpost.ru>
1 parent 37b3257 commit c451b28

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/Npgsql/NpgsqlConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void GetPoolAndSettings()
195195
{
196196
// If the pool we created was the one that ended up being stored we need to increment the appropriate counter.
197197
// Avoids a race condition where multiple threads will create a pool but only one will be stored.
198-
NpgsqlEventSource.Log.PoolCreated();
198+
NpgsqlEventSource.Log.PoolCreated(newPool);
199199
}
200200

201201
_pool = PoolManager.GetOrAdd(_connectionString, _pool);

src/Npgsql/NpgsqlEventSource.cs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics;
34
using System.Threading;
45
using System.Diagnostics.Tracing;
@@ -42,7 +43,8 @@ sealed class NpgsqlEventSource : EventSource
4243
long _currentCommands;
4344
long _failedCommands;
4445

45-
int _pools;
46+
readonly object _poolsLock = new();
47+
readonly HashSet<ConnectorPool> _pools = new();
4648

4749
long _multiplexingBatchesSent;
4850
long _multiplexingCommandsSent;
@@ -79,7 +81,13 @@ public void CommandStop()
7981

8082
internal void CommandFailed() => Interlocked.Increment(ref _failedCommands);
8183

82-
internal void PoolCreated() => Interlocked.Increment(ref _pools);
84+
internal void PoolCreated(ConnectorPool pool)
85+
{
86+
lock (_poolsLock)
87+
{
88+
_pools.Add(pool);
89+
}
90+
}
8391

8492
internal void MultiplexingBatchSent(int numCommands, int waits, Stopwatch stopwatch)
8593
{
@@ -91,35 +99,42 @@ internal void MultiplexingBatchSent(int numCommands, int waits, Stopwatch stopwa
9199
}
92100

93101
#if !NETSTANDARD2_0
94-
static int GetIdleConnections()
102+
int GetIdleConnections()
95103
{
96104
// Note: there's no attempt here to be coherent in terms of race conditions, especially not with regards
97105
// to different counters. So idle and busy and be unsynchronized, as they're not polled together.
98-
var sum = 0;
99-
foreach (var kv in PoolManager.Pools)
106+
lock (_poolsLock)
100107
{
101-
var pool = kv.Pool;
102-
if (pool == null)
103-
return sum;
104-
sum += pool.Statistics.Idle;
108+
var sum = 0;
109+
foreach (var pool in _pools)
110+
{
111+
sum += pool.Statistics.Idle;
112+
}
113+
return sum;
105114
}
106-
return sum;
107115
}
108116

109-
static int GetBusyConnections()
117+
int GetBusyConnections()
110118
{
111119
// Note: there's no attempt here to be coherent in terms of race conditions, especially not with regards
112120
// to different counters. So idle and busy and be unsynchronized, as they're not polled together.
113-
var sum = 0;
114-
foreach (var kv in PoolManager.Pools)
121+
lock (_poolsLock)
122+
{
123+
var sum = 0;
124+
foreach (var pool in _pools)
125+
{
126+
sum += pool.Statistics.Busy;
127+
}
128+
return sum;
129+
}
130+
}
131+
132+
int GetPoolsCount()
133+
{
134+
lock (_poolsLock)
115135
{
116-
var pool = kv.Pool;
117-
if (pool == null)
118-
return sum;
119-
var (_, _, busy) = pool.Statistics;
120-
sum += busy;
136+
return _pools.Count;
121137
}
122-
return sum;
123138
}
124139

125140
protected override void OnEventCommand(EventCommandEventArgs command)
@@ -174,7 +189,7 @@ protected override void OnEventCommand(EventCommandEventArgs command)
174189
DisplayUnits = "%"
175190
};
176191

177-
_poolsCounter = new PollingCounter("connection-pools", this, () => _pools)
192+
_poolsCounter = new PollingCounter("connection-pools", this, () => GetPoolsCount())
178193
{
179194
DisplayName = "Connection Pools"
180195
};

0 commit comments

Comments
 (0)