diff --git a/src/EFCore.Ydb/test/EntityFrameworkCore.Ydb.FunctionalTests/TestUtilities/YdbTestStore.cs b/src/EFCore.Ydb/test/EntityFrameworkCore.Ydb.FunctionalTests/TestUtilities/YdbTestStore.cs index 92683fd7..2ede0d60 100644 --- a/src/EFCore.Ydb/test/EntityFrameworkCore.Ydb.FunctionalTests/TestUtilities/YdbTestStore.cs +++ b/src/EFCore.Ydb/test/EntityFrameworkCore.Ydb.FunctionalTests/TestUtilities/YdbTestStore.cs @@ -181,7 +181,7 @@ private static YdbCommand CreateCommand( } - private static YdbConnection CreateConnection() => new(new YdbConnectionStringBuilder { MaxSessionPool = 10 }); + private static YdbConnection CreateConnection() => new(new YdbConnectionStringBuilder { MaxPoolSize = 10 }); public override async Task CleanAsync(DbContext context) { diff --git a/src/Ydb.Sdk/CHANGELOG.md b/src/Ydb.Sdk/CHANGELOG.md index 24ae80ae..c2448da3 100644 --- a/src/Ydb.Sdk/CHANGELOG.md +++ b/src/Ydb.Sdk/CHANGELOG.md @@ -1,3 +1,6 @@ +- **Breaking Change**: Renamed properties in `YdbConnectionStringBuilder`: + - `MaxSessionPool` -> `MaxPoolSize`. + - `MinSessionPool` -> `MinPoolSize`. - Added XML documentation for all public APIs in `Ydb.Sdk`. - Feat ADO.NET: Added dispose timeout (10 seconds) to `PoolingSessionSource`. - Feat ADO.NET: Added `EnableImplicitSession` to support implicit sessions. @@ -43,8 +46,8 @@ - Fixed bug: Grpc.Core.StatusCode.Cancelled was mapped to server's Canceled status. - Feat ADO.NET: PoolingSessionSource 2.0 based on lock-free FIFO pooling algorithm. - Added new ADO.NET options: - - `MinSessionPool`: The minimum connection pool size. - - `SessionIdleTimeout`: The time (in seconds) to wait before closing idle session in the pool if the count of all sessions exceeds `MinSessionPool`. + - `MinPoolSize`: The minimum session pool size. + - `SessionIdleTimeout`: The time (in seconds) to wait before closing idle session in the pool if the count of all sessions exceeds `MinPoolSize`. - Fixed bug `Reader`: unhandled exception in `TryReadRequestBytes(long bytes)`. - Handle `YdbException` on `DeleteSession`. - Do not invoke `DeleteSession` if the session is not active. diff --git a/src/Ydb.Sdk/src/Ado/Session/PoolingSessionSource.cs b/src/Ydb.Sdk/src/Ado/Session/PoolingSessionSource.cs index 7cc57d1d..6ab4d011 100644 --- a/src/Ydb.Sdk/src/Ado/Session/PoolingSessionSource.cs +++ b/src/Ydb.Sdk/src/Ado/Session/PoolingSessionSource.cs @@ -16,8 +16,8 @@ internal sealed class PoolingSessionSource : ISessionSource where T : Pooling private readonly CancellationTokenSource _disposeCts = new(); private readonly IPoolingSessionFactory _sessionFactory; - private readonly int _minSessionSize; - private readonly int _maxSessionSize; + private readonly int _minSizePool; + private readonly int _maxSizePool; private readonly T?[] _sessions; private readonly int _createSessionTimeout; private readonly TimeSpan _sessionIdleTimeout; @@ -32,16 +32,16 @@ internal sealed class PoolingSessionSource : ISessionSource where T : Pooling public PoolingSessionSource(IPoolingSessionFactory sessionFactory, YdbConnectionStringBuilder settings) { _sessionFactory = sessionFactory; - _minSessionSize = settings.MinSessionPool; - _maxSessionSize = settings.MaxSessionPool; + _minSizePool = settings.MinPoolSize; + _maxSizePool = settings.MaxPoolSize; - if (_minSessionSize > _maxSessionSize) + if (_minSizePool > _maxSizePool) { throw new ArgumentException( - $"Connection can't have 'Max Session Pool' {_maxSessionSize} under 'Min Session Pool' {_minSessionSize}"); + $"Connection can't have 'Max Session Pool' {_maxSizePool} under 'Min Session Pool' {_minSizePool}"); } - _sessions = new T?[_maxSessionSize]; + _sessions = new T?[_maxSizePool]; _createSessionTimeout = settings.CreateSessionTimeout; _sessionIdleTimeout = TimeSpan.FromSeconds(settings.SessionIdleTimeout); _cleanerTimer = new Timer(CleanIdleSessions, this, _sessionIdleTimeout, _sessionIdleTimeout); @@ -129,8 +129,8 @@ private async ValueTask RentAsync(CancellationToken cancellationToken) } await using var _ = finalToken.Register(() => waiterTcs.TrySetException( - new YdbException($"The connection pool has been exhausted, either raise 'MaxSessionPool' " + - $"(currently {_maxSessionSize}) or 'CreateSessionTimeout' " + + new YdbException($"The connection pool has been exhausted, either raise 'MaxPoolSize' " + + $"(currently {_maxSizePool}) or 'CreateSessionTimeout' " + $"(currently {_createSessionTimeout} seconds) in your connection string.") ), useSynchronizationContext: false ); @@ -151,7 +151,7 @@ private async ValueTask RentAsync(CancellationToken cancellationToken) private async ValueTask OpenNewSession(CancellationToken cancellationToken) { - for (var numSessions = _numSessions; numSessions < _maxSessionSize; numSessions = _numSessions) + for (var numSessions = _numSessions; numSessions < _maxSizePool; numSessions = _numSessions) { if (Interlocked.CompareExchange(ref _numSessions, numSessions + 1, numSessions) != numSessions) continue; @@ -164,7 +164,7 @@ private async ValueTask RentAsync(CancellationToken cancellationToken) var session = _sessionFactory.NewSession(this); await session.Open(cancellationToken); - for (var i = 0; i < _maxSessionSize; i++) + for (var i = 0; i < _maxSizePool; i++) { if (Interlocked.CompareExchange(ref _sessions[i], session, null) == null) return session; @@ -221,11 +221,11 @@ public void Return(T session) private void CloseSession(T session) { var i = 0; - for (; i < _maxSessionSize; i++) + for (; i < _maxSizePool; i++) if (Interlocked.CompareExchange(ref _sessions[i], null, session) == session) break; - if (i == _maxSessionSize) + if (i == _maxSizePool) return; _ = session.DeleteSession(); @@ -242,13 +242,13 @@ private static void CleanIdleSessions(object? state) var pool = (PoolingSessionSource)state!; var now = DateTime.Now; - for (var i = 0; i < pool._maxSessionSize; i++) + for (var i = 0; i < pool._maxSizePool; i++) { var session = Volatile.Read(ref pool._sessions[i]); if ( session != null && - pool._numSessions > pool._minSessionSize && + pool._numSessions > pool._minSizePool && session.IdleStartTime + pool._sessionIdleTimeout <= now && session.CompareAndSet(PoolingSessionState.In, PoolingSessionState.Clean) ) @@ -272,7 +272,7 @@ public async ValueTask DisposeAsync() var spinWait = new SpinWait(); do { - for (var i = 0; i < _maxSessionSize; i++) + for (var i = 0; i < _maxSizePool; i++) { var session = Volatile.Read(ref _sessions[i]); @@ -294,7 +294,7 @@ public async ValueTask DisposeAsync() _logger.LogError(e, "Failed to dispose the transport driver"); } - for (var i = 0; i < _maxSessionSize; i++) + for (var i = 0; i < _maxSizePool; i++) { var session = Volatile.Read(ref _sessions[i]); diff --git a/src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs b/src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs index 3f3f081c..f4bbff2e 100644 --- a/src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs +++ b/src/Ydb.Sdk/src/Ado/YdbConnectionStringBuilder.cs @@ -50,8 +50,8 @@ private void InitDefaultValues() _host = "localhost"; _port = 2136; _database = "/local"; - _minSessionPool = 0; - _maxSessionPool = 100; + _minPoolSize = 0; + _maxPoolSize = 100; _createSessionTimeout = 5; _sessionIdleTimeout = 300; _useTls = false; @@ -177,9 +177,9 @@ public string? Password /// in the session pool. Must be greater than 0. /// Default value: 100. /// - public int MaxSessionPool + public int MaxPoolSize { - get => _maxSessionPool; + get => _maxPoolSize; set { if (value <= 0) @@ -187,12 +187,12 @@ public int MaxSessionPool throw new ArgumentOutOfRangeException(nameof(value), value, "Invalid max session pool: " + value); } - _maxSessionPool = value; - SaveValue(nameof(MaxSessionPool), value); + _maxPoolSize = value; + SaveValue(nameof(MaxPoolSize), value); } } - private int _maxSessionPool; + private int _maxPoolSize; /// /// Gets or sets the minimum number of sessions in the pool. @@ -202,9 +202,9 @@ public int MaxSessionPool /// Must be greater than or equal to 0. /// Default value: 0. /// - public int MinSessionPool + public int MinPoolSize { - get => _minSessionPool; + get => _minPoolSize; set { if (value < 0) @@ -212,12 +212,12 @@ public int MinSessionPool throw new ArgumentOutOfRangeException(nameof(value), value, "Invalid min session pool: " + value); } - _minSessionPool = value; - SaveValue(nameof(MinSessionPool), value); + _minPoolSize = value; + SaveValue(nameof(MinPoolSize), value); } } - private int _minSessionPool; + private int _minPoolSize; /// /// Gets or sets the session idle timeout in seconds. @@ -392,7 +392,7 @@ public bool EnableMultipleHttp2Connections /// Specifies the maximum size of messages that can be sent to the server. /// Note: server-side limit is 64 MB. Exceeding this limit may result in /// "resource exhausted" errors or unpredictable behavior. - /// Default value: 4194304 bytes (4 MB). + /// Default value: 67108864 bytes (64 MB). /// public int MaxSendMessageSize { @@ -411,7 +411,7 @@ public int MaxSendMessageSize /// /// /// Specifies the maximum size of messages that can be received from the server. - /// Default value: 4194304 bytes (4 MB). + /// Default value: 67108864 bytes (64 MB). /// public int MaxReceiveMessageSize { @@ -679,12 +679,12 @@ static YdbConnectionOption() (builder, user) => builder.User = user), "User", "Username", "UserId", "User Id"); AddOption(new YdbConnectionOption(StringExtractor, (builder, password) => builder.Password = password), "Password", "PWD", "PSW"); - AddOption(new YdbConnectionOption(IntExtractor, (builder, maxSessionPool) => - builder.MaxSessionPool = maxSessionPool), "MaxSessionPool", "Max Session Pool", "Maximum Pool Size", - "MaximumPoolSize", "Max Pool Size", "MaxPoolSize", "MaxSessionSize", "Max Session Size"); - AddOption(new YdbConnectionOption(IntExtractor, (builder, minSessionSize) => - builder.MinSessionPool = minSessionSize), "MinSessionPool", "Min Session Pool", "Minimum Pool Size", - "MinimumPoolSize", "Min Pool Size", "MinPoolSize", "MinSessionSize", "Min Session Size"); + AddOption(new YdbConnectionOption(IntExtractor, + (builder, maxPoolSize) => builder.MaxPoolSize = maxPoolSize), + "Maximum Pool Size", "MaximumPoolSize", "Max Pool Size", "MaxPoolSize"); + AddOption(new YdbConnectionOption(IntExtractor, + (builder, minPoolSize) => builder.MinPoolSize = minPoolSize), + "Minimum Pool Size", "MinimumPoolSize", "Min Pool Size", "MinPoolSize"); AddOption(new YdbConnectionOption(BoolExtractor, (builder, useTls) => builder.UseTls = useTls), "UseTls", "Use Tls"); AddOption(new YdbConnectionOption(StringExtractor, diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Benchmarks/SessionSourceBenchmark.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Benchmarks/SessionSourceBenchmark.cs index f923d637..acca3e12 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Benchmarks/SessionSourceBenchmark.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Benchmarks/SessionSourceBenchmark.cs @@ -15,7 +15,7 @@ public class SessionSourceBenchmark [GlobalSetup] public void Setup() { - var settings = new YdbConnectionStringBuilder { MaxSessionPool = SessionPoolSize }; + var settings = new YdbConnectionStringBuilder { MaxPoolSize = SessionPoolSize }; _poolingSessionSource = new PoolingSessionSource(new MockSessionFactory(), settings); } diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Specification.Tests/YdbFactoryFixture.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Specification.Tests/YdbFactoryFixture.cs index 02f52dc8..b8d0db1e 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Specification.Tests/YdbFactoryFixture.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Specification.Tests/YdbFactoryFixture.cs @@ -7,5 +7,5 @@ public class YdbFactoryFixture : IDbFactoryFixture { public DbProviderFactory Factory => YdbProviderFactory.Instance; - public string ConnectionString => "Host=localhost;Port=2136;Database=local;MaxSessionPool=10"; + public string ConnectionString => "Host=localhost;Port=2136;Database=local;MaxPoolSize=10"; } diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/LoadTank.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/LoadTank.cs index 8439a6fe..8bb92ff3 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/LoadTank.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/LoadTank.cs @@ -43,7 +43,7 @@ Starting YDB ADO.NET Stress Test Tank var workers = new List(); ctsStep1.CancelAfter(_config.TotalTestTimeSeconds * 500); - for (var i = 0; i < _settings.MaxSessionPool; i++) + for (var i = 0; i < _settings.MaxPoolSize; i++) { workers.Add(Task.Run(async () => { @@ -72,7 +72,7 @@ Starting YDB ADO.NET Stress Test Tank _logger.LogInformation("[{Now}] Starting shooting without PoolingSessionSource...", DateTime.Now); var ctsStep2 = new CancellationTokenSource(); ctsStep2.CancelAfter(_config.TotalTestTimeSeconds * 500); - for (var i = 0; i < _settings.MaxSessionPool; i++) + for (var i = 0; i < _settings.MaxPoolSize; i++) { workers.Add(Task.Run(async () => { diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/PoolManagerTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/PoolManagerTests.cs index 840ec21a..17d9ec6b 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/PoolManagerTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/PoolManagerTests.cs @@ -9,31 +9,31 @@ public class PoolManagerTests [Theory] [InlineData(new[] { - "MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=3", - "MinSessionSize=1;DisableDiscovery=True", "MinSessionSize=2;DisableDiscovery=True" + "MinPoolSize=1", "MinPoolSize=2", "MinPoolSize=3", + "MinPoolSize=1;DisableDiscovery=True", "MinPoolSize=2;DisableDiscovery=True" }, 2, 5)] // 2 transports (by the DisableDiscovery flag), 5 pools [InlineData( - new[] { "MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=3", "MinSessionSize=4", "MinSessionSize=5" }, + new[] { "MinPoolSize=1", "MinPoolSize=2", "MinPoolSize=3", "MinPoolSize=4", "MinPoolSize=5" }, 1, 5)] // 1 transport, 5 five pools [InlineData(new[] - { "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=3" }, 1, + { "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=3" }, 1, 3)] // duplicate rows — we expect 1 transport, 3 pools [InlineData(new[] { - "MinSessionSize=1;ConnectTimeout=5", "MinSessionSize=1;ConnectTimeout=6", "MinSessionSize=1;ConnectTimeout=7", - "MinSessionSize=1;ConnectTimeout=8", "MinSessionSize=1;ConnectTimeout=9" + "MinPoolSize=1;ConnectTimeout=5", "MinPoolSize=1;ConnectTimeout=6", "MinPoolSize=1;ConnectTimeout=7", + "MinPoolSize=1;ConnectTimeout=8", "MinPoolSize=1;ConnectTimeout=9" }, 5, 5)] // 5 transport, 5 five pools - [InlineData(new[] { "MinSessionSize=1" }, 1, 1)] // simple case + [InlineData(new[] { "MinPoolSize=1" }, 1, 1)] // simple case [InlineData(new[] { - "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", - "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", - "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", - "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", "MinSessionSize=1", - "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", - "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", - "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=2", "MinSessionSize=3", - "MinSessionSize=3", "MinSessionSize=3", "MinSessionSize=3", "MinSessionSize=3", "MinSessionSize=3" + "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", + "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", + "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", + "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", "MinPoolSize=1", + "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", + "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", + "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=2", "MinPoolSize=3", + "MinPoolSize=3", "MinPoolSize=3", "MinPoolSize=3", "MinPoolSize=3", "MinPoolSize=3" }, 1, 3)] // duplicate rows — we expect 1 transport, 3 pools, stress test public async Task PoolManager_CachingAndCleanup(string[] connectionStrings, int expectedDrivers, int expectedPools) { diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/MockPoolingSessionFactory.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/MockPoolingSessionFactory.cs index 946f62d5..c155434d 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/MockPoolingSessionFactory.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/MockPoolingSessionFactory.cs @@ -4,7 +4,7 @@ namespace Ydb.Sdk.Ado.Tests.Session; -internal class MockPoolingSessionFactory(int maxSessionSize) : IPoolingSessionFactory +internal class MockPoolingSessionFactory(int maxPoolSize) : IPoolingSessionFactory { private int _sessionOpened; private int _numSession; @@ -25,7 +25,7 @@ public MockPoolingSession NewSession(PoolingSessionSource so { await Open(sessionCountOpened); - Assert.True(Interlocked.Increment(ref _numSession) <= maxSessionSize); + Assert.True(Interlocked.Increment(ref _numSession) <= maxPoolSize); await Task.Yield(); }, diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/PoolingSessionSourceMockTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/PoolingSessionSourceMockTests.cs index b3ccd63a..706b9b7c 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/PoolingSessionSourceMockTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/PoolingSessionSourceMockTests.cs @@ -7,9 +7,9 @@ namespace Ydb.Sdk.Ado.Tests.Session; public class PoolingSessionSourceMockTests { [Fact] - public void MinSessionPool_bigger_than_MaxSessionPool_throws() => Assert.Throws(() => + public void MinSessionPool_bigger_than_MaxPoolSize_throws() => Assert.Throws(() => new PoolingSessionSource(new MockPoolingSessionFactory(1), - new YdbConnectionStringBuilder { MaxSessionPool = 1, MinSessionPool = 2 }) + new YdbConnectionStringBuilder { MaxPoolSize = 1, MinPoolSize = 2 }) ); [Fact] @@ -35,24 +35,24 @@ public async Task Creating_Session_Throw_Exception() for (var it = 0; it < 10_000; it++) { const string errorMessage = "Error on open session"; - const int maxSessionSize = 200; + const int maxPoolSize = 200; - var mockPoolingSessionFactory = new MockPoolingSessionFactory(maxSessionSize) + var mockPoolingSessionFactory = new MockPoolingSessionFactory(maxPoolSize) { Open = sessionNum => - sessionNum <= maxSessionSize * 2 + sessionNum <= maxPoolSize * 2 ? Task.FromException(new YdbException(errorMessage)) : Task.CompletedTask }; var sessionSource = new PoolingSessionSource( - mockPoolingSessionFactory, new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize } + mockPoolingSessionFactory, new YdbConnectionStringBuilder { MaxPoolSize = maxPoolSize } ); var tasks = new List(); var countSuccess = 0; - for (var i = 0; i < maxSessionSize * 4; i++) + for (var i = 0; i < maxPoolSize * 4; i++) { tasks.Add(Task.Run(async () => { @@ -61,7 +61,7 @@ public async Task Creating_Session_Throw_Exception() using var session = await sessionSource.OpenSession(); // ReSharper disable once AccessToModifiedClosure Interlocked.Increment(ref countSuccess); - Assert.True(session.SessionId() > maxSessionSize * 2); + Assert.True(session.SessionId() > maxPoolSize * 2); } catch (YdbException e) { @@ -71,9 +71,9 @@ public async Task Creating_Session_Throw_Exception() } await Task.WhenAll(tasks); - Assert.Equal(maxSessionSize * 2, Volatile.Read(ref countSuccess)); - Assert.True(maxSessionSize * 3 >= mockPoolingSessionFactory.SessionOpenedCount); - Assert.True(maxSessionSize * 2 < mockPoolingSessionFactory.SessionOpenedCount); + Assert.Equal(maxPoolSize * 2, Volatile.Read(ref countSuccess)); + Assert.True(maxPoolSize * 3 >= mockPoolingSessionFactory.SessionOpenedCount); + Assert.True(maxPoolSize * 2 < mockPoolingSessionFactory.SessionOpenedCount); } } @@ -81,10 +81,10 @@ public async Task Creating_Session_Throw_Exception() public async Task HighContention_OpenClose_NotCanceledException() { const int highContentionTasks = 100; - const int maxSessionSize = highContentionTasks / 2; - var mockPoolingSessionFactory = new MockPoolingSessionFactory(maxSessionSize); + const int maxPoolSize = highContentionTasks / 2; + var mockPoolingSessionFactory = new MockPoolingSessionFactory(maxPoolSize); var sessionSource = new PoolingSessionSource( - mockPoolingSessionFactory, new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize } + mockPoolingSessionFactory, new YdbConnectionStringBuilder { MaxPoolSize = maxPoolSize } ); for (var it = 0; it < 100_000; it++) @@ -96,7 +96,7 @@ public async Task HighContention_OpenClose_NotCanceledException() tasks[i] = Task.Run(async () => { using var session = await sessionSource.OpenSession(); - Assert.True(session.SessionId() <= maxSessionSize); + Assert.True(session.SessionId() <= maxPoolSize); await Task.Yield(); }); } @@ -108,20 +108,20 @@ public async Task HighContention_OpenClose_NotCanceledException() [Fact] public async Task DisposeAsync_Cancel_WaitersSession() { - const int maxSessionSize = 10; - var mockFactory = new MockPoolingSessionFactory(maxSessionSize); + const int maxPoolSize = 10; + var mockFactory = new MockPoolingSessionFactory(maxPoolSize); var sessionSource = new PoolingSessionSource( - mockFactory, new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize } + mockFactory, new YdbConnectionStringBuilder { MaxPoolSize = maxPoolSize } ); var openSessions = new List(); var waitingSessionTasks = new List(); - for (var i = 0; i < maxSessionSize; i++) + for (var i = 0; i < maxPoolSize; i++) { openSessions.Add(await sessionSource.OpenSession()); } - for (var i = 0; i < maxSessionSize; i++) + for (var i = 0; i < maxPoolSize; i++) { waitingSessionTasks.Add(Task.Run(async () => { @@ -130,16 +130,16 @@ public async Task DisposeAsync_Cancel_WaitersSession() } var disposeTask = Task.Run(async () => await sessionSource.DisposeAsync()); - Assert.Equal(maxSessionSize, mockFactory.NumSession); + Assert.Equal(maxPoolSize, mockFactory.NumSession); await Task.Delay(5_000); - for (var i = 0; i < maxSessionSize; i++) + for (var i = 0; i < maxPoolSize; i++) { openSessions[i].Dispose(); } await disposeTask; Assert.Equal(0, mockFactory.NumSession); - for (var i = 0; i < maxSessionSize; i++) + for (var i = 0; i < maxPoolSize; i++) { Assert.StartsWith("The session source has been closed.", (await Assert.ThrowsAsync(() => waitingSessionTasks[i])).Message); @@ -153,11 +153,11 @@ public async Task DisposeAsync_Cancel_WaitersSession() public async Task StressTest_DisposeAsync_Close_Driver() { const int contentionTasks = 200; - const int maxSessionSize = 100; + const int maxPoolSize = 100; for (var it = 0; it < 100_000; it++) { var disposeCalled = false; - var mockFactory = new MockPoolingSessionFactory(maxSessionSize) + var mockFactory = new MockPoolingSessionFactory(maxPoolSize) { Dispose = () => { @@ -165,7 +165,7 @@ public async Task StressTest_DisposeAsync_Close_Driver() return ValueTask.CompletedTask; } }; - var settings = new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize }; + var settings = new YdbConnectionStringBuilder { MaxPoolSize = maxPoolSize }; var sessionSource = new PoolingSessionSource(mockFactory, settings); var openSessionTasks = new List(); for (var i = 0; i < contentionTasks; i++) @@ -207,8 +207,8 @@ public async Task StressTest_DisposeAsync_Close_Driver() public async Task DisposeAsync_WhenSessionIsLeaked_ThrowsYdbExceptionWithTimeoutMessage() { var disposeCalled = false; - const int maxSessionSize = 10; - var mockFactory = new MockPoolingSessionFactory(maxSessionSize) + const int maxPoolSize = 10; + var mockFactory = new MockPoolingSessionFactory(maxPoolSize) { Dispose = () => { @@ -216,7 +216,7 @@ public async Task DisposeAsync_WhenSessionIsLeaked_ThrowsYdbExceptionWithTimeout return ValueTask.CompletedTask; } }; - var settings = new YdbConnectionStringBuilder { MaxSessionPool = maxSessionSize }; + var settings = new YdbConnectionStringBuilder { MaxPoolSize = maxPoolSize }; var sessionSource = new PoolingSessionSource(mockFactory, settings); #pragma warning disable CA2012 @@ -232,23 +232,23 @@ await Assert.ThrowsAsync(() => } [Fact] - public async Task IdleTimeout_MinSessionSize_CloseNumSessionsMinusMinSessionCount() + public async Task IdleTimeout_MinPoolSize_CloseNumSessionsMinusMinSessionCount() { - const int maxSessionSize = 50; - const int minSessionSize = 10; + const int maxPoolSize = 50; + const int minPoolSize = 10; const int idleTimeoutSeconds = 1; - var mockFactory = new MockPoolingSessionFactory(maxSessionSize); + var mockFactory = new MockPoolingSessionFactory(maxPoolSize); var settings = new YdbConnectionStringBuilder { SessionIdleTimeout = idleTimeoutSeconds, - MaxSessionPool = maxSessionSize, - MinSessionPool = minSessionSize + MaxPoolSize = maxPoolSize, + MinPoolSize = minPoolSize }; var sessionSource = new PoolingSessionSource(mockFactory, settings); var openSessions = new List(); - for (var it = 0; it < maxSessionSize; it++) + for (var it = 0; it < maxPoolSize; it++) { openSessions.Add(await sessionSource.OpenSession()); } @@ -259,10 +259,10 @@ public async Task IdleTimeout_MinSessionSize_CloseNumSessionsMinusMinSessionCoun } await Task.Delay(TimeSpan.FromSeconds(idleTimeoutSeconds * 5)); // cleaning idle sessions - Assert.Equal(minSessionSize, mockFactory.NumSession); + Assert.Equal(minPoolSize, mockFactory.NumSession); var openSessionTasks = new List>(); - for (var it = 0; it < minSessionSize; it++) + for (var it = 0; it < minPoolSize; it++) { openSessionTasks.Add(Task.Run(async () => await sessionSource.OpenSession())); } @@ -272,8 +272,8 @@ public async Task IdleTimeout_MinSessionSize_CloseNumSessionsMinusMinSessionCoun (await it).Dispose(); } - Assert.Equal(minSessionSize, mockFactory.NumSession); - Assert.Equal(maxSessionSize, mockFactory.SessionOpenedCount); + Assert.Equal(minPoolSize, mockFactory.NumSession); + Assert.Equal(maxPoolSize, mockFactory.SessionOpenedCount); } [Fact] @@ -282,12 +282,12 @@ public async Task StressTest_HighContention_OpenClose() var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromMinutes(1)); - const int maxSessionSize = 50; - const int minSessionSize = 10; - const int highContentionTasks = maxSessionSize * 5; + const int maxPoolSize = 50; + const int minPoolSize = 10; + const int highContentionTasks = maxPoolSize * 5; var sessionIdIsBroken = new ConcurrentDictionary(); - var mockFactory = new MockPoolingSessionFactory(maxSessionSize) + var mockFactory = new MockPoolingSessionFactory(maxPoolSize) { IsBroken = sessionNum => { @@ -302,7 +302,7 @@ public async Task StressTest_HighContention_OpenClose() } }; var settings = new YdbConnectionStringBuilder - { MaxSessionPool = maxSessionSize, MinSessionPool = minSessionSize }; + { MaxPoolSize = maxPoolSize, MinPoolSize = minPoolSize }; var sessionSource = new PoolingSessionSource(mockFactory, settings); var workers = new List(); @@ -319,7 +319,7 @@ public async Task StressTest_HighContention_OpenClose() Assert.False(sessionIdIsBroken[session.SessionId()]); } - await Task.Delay(Random.Shared.Next(maxSessionSize), cts.Token); + await Task.Delay(Random.Shared.Next(maxPoolSize), cts.Token); } } catch (OperationCanceledException) @@ -340,8 +340,8 @@ public async Task Get_Session_From_Exhausted_Pool() var mockFactory = new MockPoolingSessionFactory(1); var settings = new YdbConnectionStringBuilder { - MaxSessionPool = 1, - MinSessionPool = 0 + MaxPoolSize = 1, + MinPoolSize = 0 }; var sessionSource = new PoolingSessionSource(mockFactory, settings); @@ -349,7 +349,7 @@ public async Task Get_Session_From_Exhausted_Pool() var cts = new CancellationTokenSource(); cts.CancelAfter(500); - Assert.Equal("The connection pool has been exhausted, either raise 'MaxSessionPool' (currently 1) " + + Assert.Equal("The connection pool has been exhausted, either raise 'MaxPoolSize' (currently 1) " + "or 'CreateSessionTimeout' (currently 5 seconds) in your connection string.", (await Assert.ThrowsAsync(async () => await sessionSource.OpenSession(cts.Token))).Message); @@ -360,40 +360,40 @@ public async Task Get_Session_From_Exhausted_Pool() [Fact] public async Task ReturnToPool_WhenSessionIsBroken_IsSkipped() { - const int maxSessionSize = 10; - var mockFactory = new MockPoolingSessionFactory(maxSessionSize) { IsBroken = _ => true }; + const int maxPoolSize = 10; + var mockFactory = new MockPoolingSessionFactory(maxPoolSize) { IsBroken = _ => true }; var settings = new YdbConnectionStringBuilder { - MaxSessionPool = maxSessionSize, - MinSessionPool = 0 + MaxPoolSize = maxPoolSize, + MinPoolSize = 0 }; var sessionSource = new PoolingSessionSource(mockFactory, settings); - for (var it = 0; it < maxSessionSize * 2; it++) + for (var it = 0; it < maxPoolSize * 2; it++) { using var session = await sessionSource.OpenSession(); } Assert.Equal(0, mockFactory.NumSession); - Assert.Equal(maxSessionSize * 2, mockFactory.SessionOpenedCount); + Assert.Equal(maxPoolSize * 2, mockFactory.SessionOpenedCount); } [Fact] public async Task CheckIdleSession_WhenIsBrokenInStack_CreateNewSession() { var isBroken = false; - const int maxSessionSize = 10; + const int maxPoolSize = 10; // ReSharper disable once AccessToModifiedClosure - var mockFactory = new MockPoolingSessionFactory(maxSessionSize) { IsBroken = _ => isBroken }; + var mockFactory = new MockPoolingSessionFactory(maxPoolSize) { IsBroken = _ => isBroken }; var settings = new YdbConnectionStringBuilder { - MaxSessionPool = maxSessionSize, - MinSessionPool = 0 + MaxPoolSize = maxPoolSize, + MinPoolSize = 0 }; var sessionSource = new PoolingSessionSource(mockFactory, settings); var openSessions = new List(); - for (var it = 0; it < maxSessionSize; it++) + for (var it = 0; it < maxPoolSize; it++) { openSessions.Add(await sessionSource.OpenSession()); } @@ -403,16 +403,16 @@ public async Task CheckIdleSession_WhenIsBrokenInStack_CreateNewSession() session.Dispose(); } - Assert.Equal(maxSessionSize, mockFactory.NumSession); + Assert.Equal(maxPoolSize, mockFactory.NumSession); isBroken = true; - for (var it = 0; it < maxSessionSize; it++) + for (var it = 0; it < maxPoolSize; it++) { using var session = await sessionSource.OpenSession(); isBroken = false; } Assert.Equal(1, mockFactory.NumSession); - Assert.Equal(maxSessionSize + 1, mockFactory.SessionOpenedCount); + Assert.Equal(maxPoolSize + 1, mockFactory.SessionOpenedCount); } } diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/RetryableSessionTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/RetryableSessionTests.cs index c27012e0..3df5bfb8 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/RetryableSessionTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Session/RetryableSessionTests.cs @@ -21,7 +21,7 @@ public async Task MoveNextAsync_WhenRetryableStatus_RetriesUpToMaxAttempts_ThenT var retryableSession = new RetryableSession(new PoolingSessionSource( factory, - new YdbConnectionStringBuilder { MaxSessionPool = 1 }), + new YdbConnectionStringBuilder { MaxPoolSize = 1 }), new YdbRetryPolicyExecutor(new YdbRetryPolicy(new YdbRetryPolicyConfig { MaxAttempts = 5 })) ); @@ -49,7 +49,7 @@ public async Task MoveNextAsync_WhenNonRetryable_ThrowsWithoutRetry() var retryableSession = new RetryableSession(new PoolingSessionSource( factory, - new YdbConnectionStringBuilder { MaxSessionPool = 1 }), + new YdbConnectionStringBuilder { MaxPoolSize = 1 }), new YdbRetryPolicyExecutor(new YdbRetryPolicy(new YdbRetryPolicyConfig { MaxAttempts = 5 })) ); @@ -89,7 +89,7 @@ public async Task MoveNextAsync_SucceedsOnThirdAttempt_StopsRetrying() var retryableSession = new RetryableSession(new PoolingSessionSource( factory, - new YdbConnectionStringBuilder { MaxSessionPool = 1 }), + new YdbConnectionStringBuilder { MaxPoolSize = 1 }), new YdbRetryPolicyExecutor(new YdbRetryPolicy(new YdbRetryPolicyConfig { MaxAttempts = 5 })) ); var inMemoryStream = await retryableSession.ExecuteQuery( diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Utils/TestUtils.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Utils/TestUtils.cs index 8ed05f4f..77a7aba3 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Utils/TestUtils.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/Utils/TestUtils.cs @@ -4,7 +4,7 @@ namespace Ydb.Sdk.Ado.Tests.Utils; public static class TestUtils { - private const string DefaultConnectionString = "Host=localhost;Port=2136;Database=local;MaxSessionPool=10"; + private const string DefaultConnectionString = "Host=localhost;Port=2136;Database=local;MaxPoolSize=10"; public static string ConnectionString => Environment.GetEnvironmentVariable("YDB_TEST_DB") ?? DefaultConnectionString; diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionStringBuilderTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionStringBuilderTests.cs index 8a7aa70a..a7915c5a 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionStringBuilderTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionStringBuilderTests.cs @@ -14,8 +14,8 @@ public void InitDefaultValues_WhenEmptyConstructorInvoke_ReturnDefaultConnection Assert.Equal(2136, ydbConnectionStringBuilder.Port); Assert.Equal("localhost", ydbConnectionStringBuilder.Host); Assert.Equal("/local", ydbConnectionStringBuilder.Database); - Assert.Equal(0, ydbConnectionStringBuilder.MinSessionPool); - Assert.Equal(100, ydbConnectionStringBuilder.MaxSessionPool); + Assert.Equal(0, ydbConnectionStringBuilder.MinPoolSize); + Assert.Equal(100, ydbConnectionStringBuilder.MaxPoolSize); Assert.Equal(5, ydbConnectionStringBuilder.CreateSessionTimeout); Assert.Equal(300, ydbConnectionStringBuilder.SessionIdleTimeout); Assert.Null(ydbConnectionStringBuilder.User); @@ -52,7 +52,7 @@ public void InitConnectionStringBuilder_WhenUnexpectedKey_ThrowException() public void InitConnectionStringBuilder_WhenExpectedKeys_ReturnUpdatedConnectionString() { var ydbConnectionStringBuilder = new YdbConnectionStringBuilder( - "Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true;MinSessionPool=10;MaxSessionPool=50;" + + "Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=true;MinPoolSize=10;MaxPoolSize=50;" + "CreateSessionTimeout=30;SessionIdleTimeout=600;ConnectTimeout=30;KeepAlivePingDelay=30;" + "KeepAlivePingTimeout=60;EnableMultipleHttp2Connections=true;MaxSendMessageSize=1000000;" + "MaxReceiveMessageSize=1000000;DisableDiscovery=true;DisableServerBalancer=true;EnableImplicitSession=true;" @@ -61,8 +61,8 @@ public void InitConnectionStringBuilder_WhenExpectedKeys_ReturnUpdatedConnection Assert.Equal(2135, ydbConnectionStringBuilder.Port); Assert.Equal("server", ydbConnectionStringBuilder.Host); Assert.Equal("/my/path", ydbConnectionStringBuilder.Database); - Assert.Equal(10, ydbConnectionStringBuilder.MinSessionPool); - Assert.Equal(50, ydbConnectionStringBuilder.MaxSessionPool); + Assert.Equal(10, ydbConnectionStringBuilder.MinPoolSize); + Assert.Equal(50, ydbConnectionStringBuilder.MaxPoolSize); Assert.Equal(30, ydbConnectionStringBuilder.CreateSessionTimeout); Assert.Equal(600, ydbConnectionStringBuilder.SessionIdleTimeout); Assert.Equal("Kirill", ydbConnectionStringBuilder.User); @@ -74,7 +74,7 @@ public void InitConnectionStringBuilder_WhenExpectedKeys_ReturnUpdatedConnection Assert.Equal(1000000, ydbConnectionStringBuilder.MaxSendMessageSize); Assert.Equal(1000000, ydbConnectionStringBuilder.MaxReceiveMessageSize); Assert.Equal("Host=server;Port=2135;Database=/my/path;User=Kirill;UseTls=True;" + - "MinSessionPool=10;MaxSessionPool=50;CreateSessionTimeout=30;" + + "MinPoolSize=10;MaxPoolSize=50;CreateSessionTimeout=30;" + "SessionIdleTimeout=600;" + "ConnectTimeout=30;KeepAlivePingDelay=30;KeepAlivePingTimeout=60;" + "EnableMultipleHttp2Connections=True;" + diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionTests.cs index adf266d6..1ba54cce 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionTests.cs @@ -10,7 +10,7 @@ public sealed class YdbConnectionTests : TestBase private static readonly TemporaryTables Tables = new(); private readonly string _connectionStringTls = - "Host=localhost;Port=2135;Database=/local;MaxSessionPool=10;RootCertificate=" + + "Host=localhost;Port=2135;Database=/local;MaxPoolSize=10;RootCertificate=" + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "ca.pem"); private volatile int _counter; @@ -19,7 +19,7 @@ public sealed class YdbConnectionTests : TestBase [Fact] public async Task ClearPool_WhenHasActiveConnection_CloseActiveConnectionOnClose() { - var connectionString = ConnectionString + ";MaxSessionPool=100"; + var connectionString = ConnectionString + ";MaxPoolSize=100"; var tasks = GenerateTasks(connectionString); tasks.Add(YdbConnection.ClearPool(new YdbConnection(connectionString))); @@ -196,7 +196,7 @@ public async Task DisableDiscovery_WhenPropertyIsTrue_SimpleWorking() public async Task OpenAsync_WhenCancelTokenIsCanceled_ThrowYdbException() { await using var connection = CreateConnection(); - connection.ConnectionString = ConnectionString + ";MinSessionPool=1"; + connection.ConnectionString = ConnectionString + ";MinPoolSize=1"; using var cts = new CancellationTokenSource(); await cts.CancelAsync(); await Assert.ThrowsAnyAsync(async () => await connection.OpenAsync(cts.Token)); diff --git a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbDataSourceTests.cs b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbDataSourceTests.cs index ee1a739a..00b13f4a 100644 --- a/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbDataSourceTests.cs +++ b/src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbDataSourceTests.cs @@ -10,7 +10,7 @@ public class YdbDataSourceTests : TestBase private readonly YdbDataSource _dataSource = new(ConnectionString); [Fact] - public async Task OpenConnectionAsync_WhenMaxSessionPool10_ReturnOpenConnection() + public async Task OpenConnectionAsync_WhenMaxPoolSizeIs10_ReturnOpenConnection() { var tasks = new Task[SelectedCount]; for (var i = 0; i < SelectedCount; i++) @@ -29,7 +29,7 @@ public async Task OpenConnectionAsync_WhenMaxSessionPool10_ReturnOpenConnection( [Fact] public void CreateCommand_FromDataSource_ReturnDbCommand() { - var dataSource = new YdbDataSource(ConnectionString + ";MaxSessionPool=5"); + var dataSource = new YdbDataSource(ConnectionString + ";MaxPoolSize=5"); for (var i = 0; i < SelectedCount; i++) { using var command = dataSource.CreateCommand("SELECT 1;");