Skip to content

Commit c9d2217

Browse files
committed
Unify Application Name and UseName. Fixes #1434
1 parent 64e4fc5 commit c9d2217

File tree

9 files changed

+80
-13
lines changed

9 files changed

+80
-13
lines changed

docs/content/api/MySqlConnector/MySqlDataSourceBuilder/UseName.md

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/content/connection-options.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,13 @@ These are the other options that MySqlConnector supports. They are set to sensib
286286
<tr id="ApplicationName">
287287
<td>Application Name, ApplicationName</td>
288288
<td>null</td>
289-
<td>Sets the <c>program_name</c> connection attribute passed to MySQL Server. This value may be displayed by diagnostic tools,
290-
e.g., as the “Program” column in “Client Connections” in <a href="https://www.mysql.com/products/workbench/">MySQL Workbench</a>.</td>
289+
<td><p>Sets the <c>program_name</c> connection attribute passed to MySQL Server. This value may be displayed by diagnostic tools,
290+
e.g., as the “Program” column in “Client Connections” in <a href="https://www.mysql.com/products/workbench/">MySQL Workbench</a>.
291+
It also sets the connection pool name reported by the <code>pool.name</code> tag associated with connection pool metrics.</p>
292+
<p>This connection string option is deprecated and is provided for backwards compatibility. Newer applications should
293+
use <a href="/api/MySqlConnector/MySqlDataSourceBuilder/UseName/"><code>MySqlDataSourceBuilder.UseName</code></a> instead.
294+
</p></td>
295+
</td>
291296
</tr>
292297
<tr id="AutoEnlist">
293298
<td>Auto Enlist, AutoEnlist</td>

docs/content/diagnostics/metrics.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,55 @@ Name | Type | Unit | Description
4141
`db.client.connections.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed; this corresponds to `MaximumPoolSize` in the connection string.
4242
`db.client.connections.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed; this corresponds to `MinimumPoolSize` in the connection string.
4343
`db.client.connections.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed; this corresponds to `MaximumPoolSize` in the connection string.
44+
45+
## Supported Tags
46+
47+
Name | Description
48+
--- | ---
49+
`pool.name` | The name of the connection pool (see below).
50+
`state` | `idle` or `used`; this tag is used with the `db.client.connections.usage` instrument.
51+
52+
## Connection Pool Name
53+
54+
A connection pool name can be specified by one of the following means:
55+
56+
### UseName
57+
58+
The `MySqlDataSourceBuilder.UseName` method can be used to specify a name for the connection pool:
59+
60+
```csharp
61+
using var dataSource = new MySqlDataSourceBuilder("...connection string...")
62+
.UseName("MyPoolName")
63+
.Build();
64+
```
65+
66+
This can also be used with dependency injection:
67+
68+
```csharp
69+
builder.Services.AddMySqlDataSource(builder.Configuration.GetConnectionString("Default"),
70+
x => x.UseName("MyPoolName"));
71+
```
72+
73+
### Keyed Services
74+
75+
Use the `AddKeyedMySqlDataSource` method to register a `MySqlDataSource` as a [keyed service](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8#keyed-di-services).
76+
If the service key is a string, it will automatically be used as the `MySqlDataSource` name.
77+
78+
```csharp
79+
builder.Services.AddKeyedMySqlDataSource("MyPoolName",
80+
builder.Configuration.GetConnectionString("MyConnectionString"));
81+
```
82+
83+
### Application Name
84+
85+
Finally, the connection pool name can be specified by setting the `Application Name` connection string option:
86+
87+
```csharp
88+
using var connection = new MySqlConnection("server=dbserver;...;Application Name=MyPoolName");
89+
```
90+
91+
If `UseName` is used, it will override the `Application Name` connection string option.
92+
93+
### Default
94+
95+
For metrics, if no pool name is specified, the connection string (without a password) will be used as the pool name.

src/MySqlConnector/Core/ConnectionPool.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,12 @@ private async ValueTask<ServerSession> ConnectSessionAsync(MySqlConnection conne
501501
if (!connectionStringBuilder.Pooling)
502502
return null;
503503

504+
if (name is not null)
505+
connectionStringBuilder.ApplicationName = name;
506+
504507
// force a new pool to be created, ignoring the cache
505508
var connectionSettings = new ConnectionSettings(connectionStringBuilder);
506-
var pool = new ConnectionPool(loggingConfiguration, connectionSettings, name);
509+
var pool = new ConnectionPool(loggingConfiguration, connectionSettings);
507510
pool.StartReaperTask();
508511
pool.StartDnsCheckTimer();
509512
return pool;
@@ -551,7 +554,7 @@ private async ValueTask<ServerSession> ConnectSessionAsync(MySqlConnection conne
551554

552555
// create a new pool and attempt to insert it; if someone else beats us to it, just use their value
553556
var connectionSettings = new ConnectionSettings(connectionStringBuilder);
554-
var newPool = new ConnectionPool(loggingConfiguration!, connectionSettings, name: null);
557+
var newPool = new ConnectionPool(loggingConfiguration!, connectionSettings);
555558
pool = s_pools.GetOrAdd(normalizedConnectionString, newPool);
556559

557560
if (pool == newPool)
@@ -591,12 +594,12 @@ static List<ConnectionPool> GetCachedPools()
591594
}
592595
}
593596

594-
private ConnectionPool(MySqlConnectorLoggingConfiguration loggingConfiguration, ConnectionSettings cs, string? name)
597+
private ConnectionPool(MySqlConnectorLoggingConfiguration loggingConfiguration, ConnectionSettings cs)
595598
{
596599
m_logger = loggingConfiguration.PoolLogger;
597600
m_connectionLogger = loggingConfiguration.ConnectionLogger;
598601
ConnectionSettings = cs;
599-
Name = name;
602+
Name = cs.ApplicationName;
600603
SslProtocols = cs.TlsVersions;
601604
m_generation = 0;
602605
m_cleanSemaphore = new(1);

src/MySqlConnector/Core/ConnectionSettings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public ConnectionSettings(MySqlConnectionStringBuilder csb)
121121
AllowPublicKeyRetrieval = csb.AllowPublicKeyRetrieval;
122122
AllowUserVariables = csb.AllowUserVariables;
123123
AllowZeroDateTime = csb.AllowZeroDateTime;
124-
ApplicationName = csb.ApplicationName;
124+
ApplicationName = csb.ApplicationName is { Length: 0 } ? null : csb.ApplicationName;
125125
AutoEnlist = csb.AutoEnlist;
126126
CancellationTimeout = csb.CancellationTimeout;
127127
ConnectionTimeout = ToSigned(csb.ConnectionTimeout);
@@ -216,7 +216,7 @@ private static MySqlGuidFormat GetEffectiveGuidFormat(MySqlGuidFormat guidFormat
216216
public bool AllowPublicKeyRetrieval { get; }
217217
public bool AllowUserVariables { get; }
218218
public bool AllowZeroDateTime { get; }
219-
public string ApplicationName { get; }
219+
public string? ApplicationName { get; }
220220
public bool AutoEnlist { get; }
221221
public int CancellationTimeout { get; }
222222
public int ConnectionTimeout { get; }

src/MySqlConnector/Core/MetricsReporter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal static class MetricsReporter
99
public static void RemoveIdle(ConnectionPool pool) => s_connectionsUsageCounter.Add(-1, pool.IdleStateTagList);
1010
public static void AddUsed(ConnectionPool pool) => s_connectionsUsageCounter.Add(1, pool.UsedStateTagList);
1111
public static void RemoveUsed(ConnectionPool pool) => s_connectionsUsageCounter.Add(-1, pool.UsedStateTagList);
12-
public static void AddTimeout(ConnectionPool? pool, ConnectionSettings connectionSettings) => s_connectionTimeouts.Add(1, new KeyValuePair<string, object?>("pool.name", pool?.Name ?? connectionSettings.ConnectionStringBuilder.GetConnectionString(includePassword: false)));
12+
public static void AddTimeout(ConnectionPool? pool, ConnectionSettings connectionSettings) => s_connectionTimeouts.Add(1, new KeyValuePair<string, object?>("pool.name", pool?.Name ?? connectionSettings.ApplicationName ?? connectionSettings.ConnectionStringBuilder.GetConnectionString(includePassword: false)));
1313
public static void RecordCreateTime(ConnectionPool pool, double seconds) => s_createTimeHistory.Record(seconds, pool.PoolNameTagList);
1414
public static void RecordUseTime(ConnectionPool pool, double seconds) => s_useTimeHistory.Record(seconds, pool.PoolNameTagList);
1515
public static void RecordWaitTime(ConnectionPool pool, double seconds) => s_waitTimeHistory.Record(seconds, pool.PoolNameTagList);

src/MySqlConnector/Core/ServerSession.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,7 @@ private void VerifyState(State state1, State state2, State state3, State state4,
17771777

17781778
internal SslProtocols SslProtocol => m_sslStream?.SslProtocol ?? SslProtocols.None;
17791779

1780-
private byte[] CreateConnectionAttributes(string programName)
1780+
private byte[] CreateConnectionAttributes(string? programName)
17811781
{
17821782
Log.CreatingConnectionAttributes(m_logger, Id);
17831783
var attributesWriter = new ByteBufferWriter();
@@ -1815,7 +1815,7 @@ private byte[] CreateConnectionAttributes(string programName)
18151815
#endif
18161816
attributesWriter.WriteLengthEncodedString("_pid");
18171817
attributesWriter.WriteLengthEncodedString(processId.ToString(CultureInfo.InvariantCulture));
1818-
if (programName.Length != 0)
1818+
if (!string.IsNullOrEmpty(programName))
18191819
{
18201820
attributesWriter.WriteLengthEncodedString("program_name");
18211821
attributesWriter.WriteLengthEncodedString(programName!);

src/MySqlConnector/MySqlDataSourceBuilder.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public MySqlDataSourceBuilder UseLoggerFactory(ILoggerFactory? loggerFactory)
3636
/// </summary>
3737
/// <param name="name">The data source name.</param>
3838
/// <returns>This builder, so that method calls can be chained.</returns>
39+
/// <remarks>The connection pool name is used to set the <c>program_name</c> connection attribute
40+
/// (which is visible to some diagnostic tools) and the <c>pool.name</c> tag supplied with
41+
/// <a href="https://mysqlconnector.net/diagnostics/metrics/">connection pool metrics</a>.</remarks>
3942
public MySqlDataSourceBuilder UseName(string? name)
4043
{
4144
m_name = name;

tests/MySqlConnector.Tests/Metrics/IConnectionCreator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public DataSourceConnectionCreator(bool usePooling, string? poolName, string? ap
1717
m_dataSource = new MySqlDataSourceBuilder(connectionStringBuilder.ConnectionString)
1818
.UseName(poolName)
1919
.Build();
20-
PoolName = poolName ?? connectionStringBuilder!.GetConnectionString(includePassword: false);
20+
PoolName = poolName ?? applicationName ?? connectionStringBuilder!.GetConnectionString(includePassword: false);
2121
}
2222

2323
public MySqlConnection OpenConnection() => m_dataSource!.OpenConnection();
@@ -34,7 +34,7 @@ public PlainConnectionCreator(bool usePooling, string? applicationName, MySqlCon
3434
connectionStringBuilder.Pooling = usePooling;
3535
connectionStringBuilder.ApplicationName = applicationName;
3636
m_connectionString = connectionStringBuilder.ConnectionString;
37-
PoolName = connectionStringBuilder.GetConnectionString(includePassword: false);
37+
PoolName = applicationName ?? connectionStringBuilder.GetConnectionString(includePassword: false);
3838
}
3939

4040
public MySqlConnection OpenConnection()

0 commit comments

Comments
 (0)