diff --git a/CHANGELOG.md b/CHANGELOG.md index c7effa80..24e8a177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +- Fix timeout error on create session +- Fix transport error on delete session + ## v0.1.4 - Add exception throwing when results truncated - lint: add line feed at file end diff --git a/src/Ydb.Sdk/src/Services/Table/CreateSession.cs b/src/Ydb.Sdk/src/Services/Table/CreateSession.cs index 1b5f640c..976ea185 100644 --- a/src/Ydb.Sdk/src/Services/Table/CreateSession.cs +++ b/src/Ydb.Sdk/src/Services/Table/CreateSession.cs @@ -6,6 +6,7 @@ namespace Ydb.Sdk.Services.Table; public class CreateSessionSettings : OperationRequestSettings { + public bool DeleteOnDispose = true; } public class CreateSessionResponse : ResponseWithResultBase @@ -24,7 +25,8 @@ internal ResultData(Session session) public Session Session { get; } - internal static ResultData FromProto(CreateSessionResult resultProto, Driver driver, string endpoint) + internal static ResultData FromProto(CreateSessionResult resultProto, Driver driver, string endpoint, + bool settingsDeleteOnDispose) { var session = new Session( driver: driver, @@ -57,13 +59,13 @@ public async Task CreateSession(CreateSessionSettings? se request: request, settings: settings); - CreateSessionResult? resultProto; - var status = UnpackOperation(response.Data.Operation, out resultProto); + var status = UnpackOperation(response.Data.Operation, out CreateSessionResult? resultProto); CreateSessionResponse.ResultData? result = null; if (status.IsSuccess && resultProto != null) { - result = CreateSessionResponse.ResultData.FromProto(resultProto, Driver, response.UsedEndpoint); + result = CreateSessionResponse.ResultData.FromProto(resultProto, Driver, response.UsedEndpoint, + settings.DeleteOnDispose); } return new CreateSessionResponse(status, result); diff --git a/src/Ydb.Sdk/src/Services/Table/Session.cs b/src/Ydb.Sdk/src/Services/Table/Session.cs index 2e3b1706..7a8c39f8 100644 --- a/src/Ydb.Sdk/src/Services/Table/Session.cs +++ b/src/Ydb.Sdk/src/Services/Table/Session.cs @@ -12,13 +12,16 @@ public partial class Session : ClientBase, IDisposable private readonly ILogger _logger; private bool _disposed; - internal Session(Driver driver, SessionPool? sessionPool, string id, string? endpoint) + private readonly bool _deleteOnDispose; + + internal Session(Driver driver, SessionPool? sessionPool, string id, string? endpoint, bool deleteOnDispose = true) : base(driver) { _sessionPool = sessionPool; _logger = Driver.LoggerFactory.CreateLogger(); Id = id; Endpoint = endpoint; + _deleteOnDispose = deleteOnDispose; } public string Id { get; } @@ -73,13 +76,17 @@ protected virtual void Dispose(bool disposing) { if (_sessionPool is null) { - _logger.LogTrace($"Closing detached session on dispose: {Id}"); - - var client = new TableClient(Driver, new NoPool()); - _ = client.DeleteSession(Id, new DeleteSessionSettings + if (_deleteOnDispose) { - TransportTimeout = DeleteSessionTimeout - }); + _logger.LogTrace($"Closing detached session on dispose: {Id}"); + + var client = new TableClient(Driver, new NoPool()); + var task = client.DeleteSession(Id, new DeleteSessionSettings + { + TransportTimeout = DeleteSessionTimeout + }); + task.Wait(); + } } else { diff --git a/src/Ydb.Sdk/src/Services/Table/SessionPool.cs b/src/Ydb.Sdk/src/Services/Table/SessionPool.cs index cf4c0115..7870b27a 100644 --- a/src/Ydb.Sdk/src/Services/Table/SessionPool.cs +++ b/src/Ydb.Sdk/src/Services/Table/SessionPool.cs @@ -17,6 +17,7 @@ public SessionPoolConfig( internal TimeSpan PeriodicCheckInterval { get; } = TimeSpan.FromSeconds(10); internal TimeSpan KeepAliveTimeout { get; } = TimeSpan.FromSeconds(1); internal TimeSpan CreateSessionTimeout { get; } = TimeSpan.FromSeconds(1); + internal bool DeleteSessionsOnDispose { get; } = true; } internal class GetSessionResponse : ResponseWithResultBase, IDisposable @@ -90,8 +91,7 @@ public async Task GetSession() { var sessionId = _idleSessions.Pop(); - SessionState? sessionState; - if (!_sessions.TryGetValue(sessionId, out sessionState)) + if (!_sessions.TryGetValue(sessionId, out var sessionState)) { continue; } @@ -120,7 +120,8 @@ public async Task GetSession() var createSessionResponse = await _client.CreateSession(new CreateSessionSettings { TransportTimeout = _config.CreateSessionTimeout, - OperationTimeout = _config.CreateSessionTimeout + OperationTimeout = _config.CreateSessionTimeout, + DeleteOnDispose = _config.DeleteSessionsOnDispose }); lock (_lock) @@ -133,7 +134,8 @@ public async Task GetSession() driver: _driver, sessionPool: this, id: createSessionResponse.Result.Session.Id, - endpoint: createSessionResponse.Result.Session.Endpoint); + endpoint: createSessionResponse.Result.Session.Endpoint, + deleteOnDispose: _config.DeleteSessionsOnDispose); _sessions.Add(session.Id, new SessionState(session)); @@ -152,14 +154,14 @@ internal void ReturnSession(string id) { lock (_lock) { - SessionState? oldSession; - if (_sessions.TryGetValue(id, out oldSession)) + if (_sessions.TryGetValue(id, out var oldSession)) { var session = new Session( driver: _driver, sessionPool: this, id: id, - endpoint: oldSession.Session.Endpoint); + endpoint: oldSession.Session.Endpoint, + deleteOnDispose: _config.DeleteSessionsOnDispose); _sessions[id] = new SessionState(session); _idleSessions.Push(id); @@ -275,14 +277,22 @@ private void Dispose(bool disposing) if (disposing) { - foreach (var state in _sessions.Values) + if (_config.DeleteSessionsOnDispose) { - _logger.LogTrace($"Closing session on session pool dispose: {state.Session.Id}"); - - _ = _client.DeleteSession(state.Session.Id, new DeleteSessionSettings + var tasks = new Task[_sessions.Count]; + var i = 0; + foreach (var state in _sessions.Values) { - TransportTimeout = Session.DeleteSessionTimeout - }); + _logger.LogTrace($"Closing session on session pool dispose: {state.Session.Id}"); + + var task = _client.DeleteSession(state.Session.Id, new DeleteSessionSettings + { + TransportTimeout = Session.DeleteSessionTimeout + }); + tasks[i++] = task; + } + + Task.WaitAll(tasks); } }