Skip to content

Commit 61ff1a0

Browse files
Feat ADO.NET: cache gRPC transport by gRPCConnectionString to reuse channels. (#520)
* Feat ADO.NET: cache gRPC transport by `gRPCConnectionString` to reuse channels. * refactoring * fix session leak in tests
1 parent 531b609 commit 61ff1a0

File tree

13 files changed

+288
-182
lines changed

13 files changed

+288
-182
lines changed

src/Ydb.Sdk/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
- Fix bug wrap-around ADO.NET: Big parameterized Decimal — `((ulong)bits[1] << 32)` -> `((ulong)(uint)bits[1] << 32)`
1+
- Feat ADO.NET: cache gRPC transport by `gRPCConnectionString` to reuse channels.
2+
- Fix bug wrap-around ADO.NET: Big parameterized Decimal — `((ulong)bits[1] << 32)` -> `((ulong)(uint)bits[1] << 32)`.
23
- Feat ADO.NET: Parameterized Decimal overflow check: `Precision` and `Scale`.
34
- Feat ADO.NET: Deleted support for `DateTimeOffset` was a mistake.
45
- Feat ADO.NET: Added support for `Date32`, `Datetime64`, `Timestamp64` and `Interval64` types in YDB.

src/Ydb.Sdk/src/Ado/PoolManager.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ namespace Ydb.Sdk.Ado;
66
internal static class PoolManager
77
{
88
private static readonly SemaphoreSlim SemaphoreSlim = new(1); // async mutex
9-
private static readonly ConcurrentDictionary<string, ISessionSource> Pools = new();
9+
10+
internal static readonly ConcurrentDictionary<string, IDriver> Drivers = new();
11+
internal static readonly ConcurrentDictionary<string, ISessionSource> Pools = new();
1012

1113
internal static async Task<ISession> GetSession(
1214
YdbConnectionStringBuilder settings,
@@ -27,9 +29,14 @@ CancellationToken cancellationToken
2729
return await pool.OpenSession(cancellationToken);
2830
}
2931

30-
var newSessionPool = new PoolingSessionSource<PoolingSession>(
31-
await PoolingSessionFactory.Create(settings), settings
32-
);
32+
var driver = Drivers.TryGetValue(settings.GrpcConnectionString, out var cacheDriver) &&
33+
!cacheDriver.IsDisposed
34+
? cacheDriver
35+
: Drivers[settings.GrpcConnectionString] = await settings.BuildDriver();
36+
driver.RegisterOwner();
37+
38+
var factory = new PoolingSessionFactory(driver, settings);
39+
var newSessionPool = new PoolingSessionSource<PoolingSession>(factory, settings);
3340

3441
Pools[settings.ConnectionString] = newSessionPool;
3542

src/Ydb.Sdk/src/Ado/Session/PoolingSessionFactory.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Extensions.Logging;
2-
using Microsoft.Extensions.Logging.Abstractions;
32

43
namespace Ydb.Sdk.Ado.Session;
54

@@ -9,16 +8,13 @@ internal class PoolingSessionFactory : IPoolingSessionFactory<PoolingSession>
98
private readonly bool _disableServerBalancer;
109
private readonly ILogger<PoolingSession> _logger;
1110

12-
internal PoolingSessionFactory(IDriver driver, YdbConnectionStringBuilder settings, ILoggerFactory loggerFactory)
11+
internal PoolingSessionFactory(IDriver driver, YdbConnectionStringBuilder settings)
1312
{
1413
_driver = driver;
1514
_disableServerBalancer = settings.DisableServerBalancer;
16-
_logger = loggerFactory.CreateLogger<PoolingSession>();
15+
_logger = settings.LoggerFactory.CreateLogger<PoolingSession>();
1716
}
1817

19-
public static async Task<PoolingSessionFactory> Create(YdbConnectionStringBuilder settings) =>
20-
new(await settings.BuildDriver(), settings, settings.LoggerFactory ?? NullLoggerFactory.Instance);
21-
2218
public PoolingSession NewSession(PoolingSessionSource<PoolingSession> source) =>
2319
new(_driver, source, _disableServerBalancer, _logger);
2420

src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public int CreateSessionTimeout
314314

315315
private int _createSessionTimeout;
316316

317-
public ILoggerFactory? LoggerFactory { get; init; }
317+
public ILoggerFactory LoggerFactory { get; init; } = NullLoggerFactory.Instance;
318318

319319
public ICredentialsProvider? CredentialsProvider { get; init; }
320320

@@ -358,6 +358,12 @@ public override object this[string keyword]
358358

359359
private string Endpoint => $"{(UseTls ? "grpcs" : "grpc")}://{Host}:{Port}";
360360

361+
internal string GrpcConnectionString =>
362+
$"UseTls={UseTls};Host={Host};Port={Port};Database={Database};User={User};Password={Password};" +
363+
$"ConnectTimeout={ConnectTimeout};KeepAlivePingDelay={KeepAlivePingDelay};KeepAlivePingTimeout={KeepAlivePingTimeout};" +
364+
$"EnableMultipleHttp2Connections={EnableMultipleHttp2Connections};MaxSendMessageSize={MaxSendMessageSize};" +
365+
$"MaxReceiveMessageSize={MaxReceiveMessageSize};DisableDiscovery={DisableDiscovery}";
366+
361367
internal async Task<IDriver> BuildDriver()
362368
{
363369
var cert = RootCertificate != null ? X509Certificate.CreateFromCertFile(RootCertificate) : null;
@@ -384,11 +390,10 @@ internal async Task<IDriver> BuildDriver()
384390
MaxSendMessageSize = MaxSendMessageSize,
385391
MaxReceiveMessageSize = MaxReceiveMessageSize
386392
};
387-
var loggerFactory = LoggerFactory ?? NullLoggerFactory.Instance;
388393

389394
return DisableDiscovery
390-
? new DirectGrpcChannelDriver(driverConfig, loggerFactory)
391-
: await Driver.CreateInitialized(driverConfig, loggerFactory);
395+
? new DirectGrpcChannelDriver(driverConfig, LoggerFactory)
396+
: await Driver.CreateInitialized(driverConfig, LoggerFactory);
392397
}
393398

394399
public override void Clear()

src/Ydb.Sdk/src/IDriver.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public ValueTask<IBidirectionalStream<TRequest, TResponse>> BidirectionalStreamC
3131
where TResponse : class;
3232

3333
ILoggerFactory LoggerFactory { get; }
34+
35+
void RegisterOwner();
36+
37+
bool IsDisposed { get; }
3438
}
3539

3640
public interface IBidirectionalStream<in TRequest, out TResponse> : IDisposable
@@ -63,6 +67,8 @@ public abstract class BaseDriver : IDriver
6367
internal readonly GrpcChannelFactory GrpcChannelFactory;
6468
internal readonly ChannelPool<GrpcChannel> ChannelPool;
6569

70+
private int _ownerCount;
71+
6672
protected int Disposed;
6773

6874
internal BaseDriver(
@@ -204,12 +210,14 @@ protected async ValueTask<CallOptions> GetCallOptions(GrpcRequestSettings settin
204210
}
205211

206212
public ILoggerFactory LoggerFactory { get; }
213+
public void RegisterOwner() => _ownerCount++;
214+
public bool IsDisposed => Disposed == 1;
207215

208216
public void Dispose() => DisposeAsync().AsTask().GetAwaiter().GetResult();
209217

210218
public async ValueTask DisposeAsync()
211219
{
212-
if (Interlocked.CompareExchange(ref Disposed, 1, 0) == 0)
220+
if (--_ownerCount <= 0 && Interlocked.CompareExchange(ref Disposed, 1, 0) == 0)
213221
{
214222
await ChannelPool.DisposeAsync();
215223

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Benchmarks/BulkUpsertImporterBenchmark.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,8 @@ public Task<TResponse>
6363
NotImplementedException();
6464

6565
public ILoggerFactory LoggerFactory => null!;
66+
67+
public void RegisterOwner() => throw new NotImplementedException();
68+
69+
public bool IsDisposed => false;
6670
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System.Collections.Immutable;
2+
using Xunit;
3+
4+
namespace Ydb.Sdk.Ado.Tests;
5+
6+
[Collection("PoolManagerTests")]
7+
[CollectionDefinition("PoolManagerTests", DisableParallelization = true)]
8+
public class PoolManagerTests
9+
{
10+
[Theory]
11+
[InlineData(new[]
12+
{
13+
"MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=3",
14+
"MinSessionSize=1;DisableDiscovery=True", "MinSessionSize=2;DisableDiscovery=True"
15+
}, 2, 5)] // 2 transports (by the DisableDiscovery flag), 5 pools
16+
[InlineData(
17+
new[] { "MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=3", "MinSessionSize=4", "MinSessionSize=5" },
18+
1, 5)] // 1 transport, 5 five pools
19+
[InlineData(new[]
20+
{ "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=3" }, 1,
21+
3)] // duplicate rows — we expect 1 transport, 3 pools
22+
[InlineData(new[]
23+
{
24+
"MinSessionSize=1;ConnectTimeout=5", "MinSessionSize=1;ConnectTimeout=6", "MinSessionSize=1;ConnectTimeout=7",
25+
"MinSessionSize=1;ConnectTimeout=8", "MinSessionSize=1;ConnectTimeout=9"
26+
}, 5, 5)] // 5 transport, 5 five pools
27+
[InlineData(new[] { "MinSessionSize=1" }, 1, 1)] // simple case
28+
public async Task PoolManager_CachingAndCleanup(string[] connectionStrings, int expectedDrivers, int expectedPools)
29+
{
30+
await YdbConnection.ClearAllPools();
31+
PoolManager.Drivers.Clear();
32+
33+
var connections = connectionStrings
34+
.Select(connectionString => new YdbConnection(connectionString))
35+
.ToImmutableArray();
36+
var parallelTasks = connections.Select(connection => connection.OpenAsync()).ToList();
37+
await Task.WhenAll(parallelTasks);
38+
39+
Assert.Equal(expectedDrivers, PoolManager.Drivers.Count);
40+
Assert.Equal(expectedPools, PoolManager.Pools.Count);
41+
42+
await ClearAllConnections(connections);
43+
44+
parallelTasks = connections.Select(connection => connection.OpenAsync()).ToList();
45+
await Task.WhenAll(parallelTasks);
46+
47+
foreach (var (_, driver) in PoolManager.Drivers)
48+
{
49+
Assert.False(driver.IsDisposed);
50+
}
51+
52+
Assert.Equal(expectedDrivers, PoolManager.Drivers.Count);
53+
Assert.Equal(expectedPools, PoolManager.Pools.Count);
54+
55+
await ClearAllConnections(connections);
56+
}
57+
58+
private static async Task ClearAllConnections(IReadOnlyCollection<YdbConnection> connections)
59+
{
60+
foreach (var connection in connections)
61+
await connection.CloseAsync();
62+
63+
await YdbConnection.ClearAllPools();
64+
Assert.Empty(PoolManager.Pools);
65+
66+
foreach (var (_, driver) in PoolManager.Drivers)
67+
{
68+
Assert.True(driver.IsDisposed);
69+
}
70+
}
71+
}

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/PoolingSessionTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class PoolingSessionTests
2121

2222
public PoolingSessionTests()
2323
{
24-
var settings = new YdbConnectionStringBuilder();
24+
var settings = new YdbConnectionStringBuilder { LoggerFactory = TestUtils.LoggerFactory };
2525

2626
_mockIDriver = new Mock<IDriver>(MockBehavior.Strict);
2727
_mockIDriver.Setup(driver => driver.LoggerFactory).Returns(TestUtils.LoggerFactory);
@@ -31,7 +31,7 @@ public PoolingSessionTests()
3131
It.Is<GrpcRequestSettings>(grpcRequestSettings => grpcRequestSettings.NodeId == NodeId))
3232
).ReturnsAsync(_mockAttachStream.Object);
3333
_mockAttachStream.Setup(stream => stream.Dispose());
34-
_poolingSessionFactory = new PoolingSessionFactory(_mockIDriver.Object, settings, TestUtils.LoggerFactory);
34+
_poolingSessionFactory = new PoolingSessionFactory(_mockIDriver.Object, settings);
3535
_poolingSessionSource = new PoolingSessionSource<PoolingSession>(_poolingSessionFactory, settings);
3636
}
3737

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbCommandTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ public async Task ExecuteReaderAsync_WhenSelectNull_ThrowFieldIsNull()
6767
dbCommand.CommandText = "SELECT NULL";
6868
var reader = await dbCommand.ExecuteReaderAsync();
6969
await reader.ReadAsync();
70-
7170
Assert.Equal("Field is null.", Assert.Throws<InvalidCastException>(() => reader.GetFloat(0)).Message);
7271
}
7372

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionStringBuilderTests.cs

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace Ydb.Sdk.Ado.Tests;
44

55
public class YdbConnectionStringBuilderTests
66
{
7+
private const int MessageSize = 64 * 1024 * 1024;
8+
79
[Fact]
810
public void InitDefaultValues_WhenEmptyConstructorInvoke_ReturnDefaultConnectionString()
911
{
@@ -23,11 +25,16 @@ public void InitDefaultValues_WhenEmptyConstructorInvoke_ReturnDefaultConnection
2325
Assert.Equal(10, ydbConnectionStringBuilder.KeepAlivePingTimeout);
2426
Assert.Equal("", ydbConnectionStringBuilder.ConnectionString);
2527
Assert.False(ydbConnectionStringBuilder.EnableMultipleHttp2Connections);
26-
Assert.Equal(64 * 1024 * 1024, ydbConnectionStringBuilder.MaxSendMessageSize);
27-
Assert.Equal(64 * 1024 * 1024, ydbConnectionStringBuilder.MaxReceiveMessageSize);
28+
Assert.Equal(MessageSize, ydbConnectionStringBuilder.MaxSendMessageSize);
29+
Assert.Equal(MessageSize, ydbConnectionStringBuilder.MaxReceiveMessageSize);
2830
Assert.False(ydbConnectionStringBuilder.DisableDiscovery);
2931
Assert.False(ydbConnectionStringBuilder.DisableServerBalancer);
3032
Assert.False(ydbConnectionStringBuilder.UseTls);
33+
34+
Assert.Equal("UseTls=False;Host=localhost;Port=2136;Database=/local;User=;Password=;ConnectTimeout=5;" +
35+
"KeepAlivePingDelay=10;KeepAlivePingTimeout=10;EnableMultipleHttp2Connections=False;" +
36+
$"MaxSendMessageSize={MessageSize};MaxReceiveMessageSize={MessageSize};DisableDiscovery=False",
37+
ydbConnectionStringBuilder.GrpcConnectionString);
3138
}
3239

3340
[Fact]
@@ -43,68 +50,81 @@ public void InitConnectionStringBuilder_WhenUnexpectedKey_ThrowException()
4350
[Fact]
4451
public void InitConnectionStringBuilder_WhenExpectedKeys_ReturnUpdatedConnectionString()
4552
{
46-
var connectionString = new YdbConnectionStringBuilder(
47-
"Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true;" +
48-
"MinSessionPool=10;MaxSessionPool=50;CreateSessionTimeout=30;" +
49-
"SessionIdleTimeout=600;" +
50-
"ConnectTimeout=30;KeepAlivePingDelay=30;KeepAlivePingTimeout=60;" +
51-
"EnableMultipleHttp2Connections=true;" +
52-
"MaxSendMessageSize=1000000;MaxReceiveMessageSize=1000000;" +
53-
"DisableDiscovery=true;DisableServerBalancer=true;"
53+
var ydbConnectionStringBuilder = new YdbConnectionStringBuilder(
54+
"Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true;MinSessionPool=10;MaxSessionPool=50;" +
55+
"CreateSessionTimeout=30;SessionIdleTimeout=600;ConnectTimeout=30;KeepAlivePingDelay=30;" +
56+
"KeepAlivePingTimeout=60;EnableMultipleHttp2Connections=true;MaxSendMessageSize=1000000;" +
57+
"MaxReceiveMessageSize=1000000;DisableDiscovery=true;DisableServerBalancer=true;"
5458
);
5559

56-
Assert.Equal(2135, connectionString.Port);
57-
Assert.Equal("server", connectionString.Host);
58-
Assert.Equal("/my/path", connectionString.Database);
59-
Assert.Equal(10, connectionString.MinSessionPool);
60-
Assert.Equal(50, connectionString.MaxSessionPool);
61-
Assert.Equal(30, connectionString.CreateSessionTimeout);
62-
Assert.Equal(600, connectionString.SessionIdleTimeout);
63-
Assert.Equal("Kirill", connectionString.User);
64-
Assert.Equal(30, connectionString.ConnectTimeout);
65-
Assert.Equal(30, connectionString.KeepAlivePingDelay);
66-
Assert.Equal(60, connectionString.KeepAlivePingTimeout);
67-
Assert.Null(connectionString.Password);
68-
Assert.True(connectionString.EnableMultipleHttp2Connections);
69-
Assert.Equal(1000000, connectionString.MaxSendMessageSize);
70-
Assert.Equal(1000000, connectionString.MaxReceiveMessageSize);
60+
Assert.Equal(2135, ydbConnectionStringBuilder.Port);
61+
Assert.Equal("server", ydbConnectionStringBuilder.Host);
62+
Assert.Equal("/my/path", ydbConnectionStringBuilder.Database);
63+
Assert.Equal(10, ydbConnectionStringBuilder.MinSessionPool);
64+
Assert.Equal(50, ydbConnectionStringBuilder.MaxSessionPool);
65+
Assert.Equal(30, ydbConnectionStringBuilder.CreateSessionTimeout);
66+
Assert.Equal(600, ydbConnectionStringBuilder.SessionIdleTimeout);
67+
Assert.Equal("Kirill", ydbConnectionStringBuilder.User);
68+
Assert.Equal(30, ydbConnectionStringBuilder.ConnectTimeout);
69+
Assert.Equal(30, ydbConnectionStringBuilder.KeepAlivePingDelay);
70+
Assert.Equal(60, ydbConnectionStringBuilder.KeepAlivePingTimeout);
71+
Assert.Null(ydbConnectionStringBuilder.Password);
72+
Assert.True(ydbConnectionStringBuilder.EnableMultipleHttp2Connections);
73+
Assert.Equal(1000000, ydbConnectionStringBuilder.MaxSendMessageSize);
74+
Assert.Equal(1000000, ydbConnectionStringBuilder.MaxReceiveMessageSize);
7175
Assert.Equal("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=True;" +
7276
"MinSessionPool=10;MaxSessionPool=50;CreateSessionTimeout=30;" +
7377
"SessionIdleTimeout=600;" +
7478
"ConnectTimeout=30;KeepAlivePingDelay=30;KeepAlivePingTimeout=60;" +
7579
"EnableMultipleHttp2Connections=True;" +
7680
"MaxSendMessageSize=1000000;MaxReceiveMessageSize=1000000;" +
77-
"DisableDiscovery=True;DisableServerBalancer=True", connectionString.ConnectionString);
78-
Assert.True(connectionString.DisableDiscovery);
79-
Assert.True(connectionString.DisableServerBalancer);
81+
"DisableDiscovery=True;DisableServerBalancer=True", ydbConnectionStringBuilder.ConnectionString);
82+
Assert.True(ydbConnectionStringBuilder.DisableDiscovery);
83+
Assert.True(ydbConnectionStringBuilder.DisableServerBalancer);
84+
Assert.Equal("UseTls=True;Host=server;Port=2135;Database=/my/path;User=Kirill;Password=;ConnectTimeout=30;" +
85+
"KeepAlivePingDelay=30;KeepAlivePingTimeout=60;EnableMultipleHttp2Connections=True;" +
86+
"MaxSendMessageSize=1000000;MaxReceiveMessageSize=1000000;DisableDiscovery=True",
87+
ydbConnectionStringBuilder.GrpcConnectionString);
8088
}
8189

8290
[Fact]
8391
public void Host_WhenSetInProperty_ReturnUpdatedConnectionString()
8492
{
85-
var connectionString = new YdbConnectionStringBuilder("Host=server;Port=2135;Database=/my/path;User=Kirill");
86-
87-
Assert.Equal("server", connectionString.Host);
88-
connectionString.Host = "new_server";
89-
Assert.Equal("new_server", connectionString.Host);
90-
91-
Assert.Equal("Host=new_server;Port=2135;Database=/my/path;User=Kirill", connectionString.ConnectionString);
93+
var ydbConnectionStringBuilder =
94+
new YdbConnectionStringBuilder("Host=server;Port=2135;Database=/my/path;User=Kirill");
95+
Assert.Equal(
96+
"UseTls=False;Host=server;Port=2135;Database=/my/path;User=Kirill;Password=;ConnectTimeout=5;" +
97+
"KeepAlivePingDelay=10;KeepAlivePingTimeout=10;EnableMultipleHttp2Connections=False;" +
98+
$"MaxSendMessageSize={MessageSize};MaxReceiveMessageSize={MessageSize};DisableDiscovery=False",
99+
ydbConnectionStringBuilder.GrpcConnectionString);
100+
Assert.Equal("server", ydbConnectionStringBuilder.Host);
101+
ydbConnectionStringBuilder.Host = "new_server";
102+
Assert.Equal("new_server", ydbConnectionStringBuilder.Host);
103+
Assert.Equal(
104+
"UseTls=False;Host=new_server;Port=2135;Database=/my/path;User=Kirill;Password=;ConnectTimeout=5;" +
105+
"KeepAlivePingDelay=10;KeepAlivePingTimeout=10;EnableMultipleHttp2Connections=False;" +
106+
$"MaxSendMessageSize={MessageSize};MaxReceiveMessageSize={MessageSize};DisableDiscovery=False",
107+
ydbConnectionStringBuilder.GrpcConnectionString);
108+
Assert.Equal("Host=new_server;Port=2135;Database=/my/path;User=Kirill",
109+
ydbConnectionStringBuilder.ConnectionString);
92110
}
93111

94112
[Fact]
95113
public void SetProperty_WhenPropertyNeedsTrimOperation_ReturnUpdatedConnectionString()
96114
{
97-
var connectionString =
115+
var ydbConnectionStringBuilder =
98116
new YdbConnectionStringBuilder(" Host =server;Port=2135; EnableMultipleHttp2Connections =true");
99117

100-
Assert.Equal(2135, connectionString.Port);
101-
Assert.Equal("server", connectionString.Host);
102-
Assert.True(connectionString.EnableMultipleHttp2Connections);
118+
Assert.Equal(2135, ydbConnectionStringBuilder.Port);
119+
Assert.Equal("server", ydbConnectionStringBuilder.Host);
120+
Assert.True(ydbConnectionStringBuilder.EnableMultipleHttp2Connections);
103121

104-
Assert.Equal("Host=server;Port=2135;EnableMultipleHttp2Connections=True", connectionString.ConnectionString);
122+
Assert.Equal("Host=server;Port=2135;EnableMultipleHttp2Connections=True",
123+
ydbConnectionStringBuilder.ConnectionString);
105124

106-
connectionString.EnableMultipleHttp2Connections = false;
125+
ydbConnectionStringBuilder.EnableMultipleHttp2Connections = false;
107126

108-
Assert.Equal("Host=server;Port=2135;EnableMultipleHttp2Connections=False", connectionString.ConnectionString);
127+
Assert.Equal("Host=server;Port=2135;EnableMultipleHttp2Connections=False",
128+
ydbConnectionStringBuilder.ConnectionString);
109129
}
110130
}

0 commit comments

Comments
 (0)