From a58d473cfe8857feda396da339026e1026a3ea75 Mon Sep 17 00:00:00 2001 From: Timothy Coleman Date: Fri, 28 Jan 2022 20:59:07 +0000 Subject: [PATCH] Adjustments to Disposal - Seal the Client classes (no finalizers here) - Make dispose/async virtual instead of explicit so it will be called in the standard way - When disposing EventStoreClient cancel the cts - When disposing EventStoreClient don't create a batchappender if there wasn't one. --- .../EventStoreOperationsClient.cs | 2 +- ...EventStorePersistentSubscriptionsClient.cs | 2 +- .../EventStoreProjectionManagementClient.cs | 2 +- .../EventStoreClient.cs | 31 +++++++++---------- .../EventStoreUserManagementClient.cs | 2 +- src/EventStore.Client/EventStoreClientBase.cs | 4 +-- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/EventStore.Client.Operations/EventStoreOperationsClient.cs b/src/EventStore.Client.Operations/EventStoreOperationsClient.cs index 5836537c1..fba4be74b 100644 --- a/src/EventStore.Client.Operations/EventStoreOperationsClient.cs +++ b/src/EventStore.Client.Operations/EventStoreOperationsClient.cs @@ -11,7 +11,7 @@ namespace EventStore.Client { /// /// The client used to perform maintenance and other administrative tasks on the EventStoreDB. /// - public partial class EventStoreOperationsClient : EventStoreClientBase { + public sealed partial class EventStoreOperationsClient : EventStoreClientBase { private static readonly IDictionary> ExceptionMap = new Dictionary> { [Constants.Exceptions.ScavengeNotFound] = ex => new ScavengeNotFoundException(ex.Trailers diff --git a/src/EventStore.Client.PersistentSubscriptions/EventStorePersistentSubscriptionsClient.cs b/src/EventStore.Client.PersistentSubscriptions/EventStorePersistentSubscriptionsClient.cs index f59ff96e6..3084c37b5 100644 --- a/src/EventStore.Client.PersistentSubscriptions/EventStorePersistentSubscriptionsClient.cs +++ b/src/EventStore.Client.PersistentSubscriptions/EventStorePersistentSubscriptionsClient.cs @@ -10,7 +10,7 @@ namespace EventStore.Client { /// /// The client used to manage persistent subscriptions in the EventStoreDB. /// - public partial class EventStorePersistentSubscriptionsClient : EventStoreClientBase { + public sealed partial class EventStorePersistentSubscriptionsClient : EventStoreClientBase { private readonly ILogger _log; /// diff --git a/src/EventStore.Client.ProjectionManagement/EventStoreProjectionManagementClient.cs b/src/EventStore.Client.ProjectionManagement/EventStoreProjectionManagementClient.cs index a2c3e1b21..0ad5463a8 100644 --- a/src/EventStore.Client.ProjectionManagement/EventStoreProjectionManagementClient.cs +++ b/src/EventStore.Client.ProjectionManagement/EventStoreProjectionManagementClient.cs @@ -10,7 +10,7 @@ namespace EventStore.Client { /// ///The client used to manage projections on the EventStoreDB. /// - public partial class EventStoreProjectionManagementClient : EventStoreClientBase { + public sealed partial class EventStoreProjectionManagementClient : EventStoreClientBase { private readonly ILogger _log; /// diff --git a/src/EventStore.Client.Streams/EventStoreClient.cs b/src/EventStore.Client.Streams/EventStoreClient.cs index 0922d22e4..4ec5e64ca 100644 --- a/src/EventStore.Client.Streams/EventStoreClient.cs +++ b/src/EventStore.Client.Streams/EventStoreClient.cs @@ -18,12 +18,7 @@ namespace EventStore.Client { /// /// The client used for operations on streams. /// - public partial class EventStoreClient : EventStoreClientBase, -// todo: remove these long with the explicit implementations -#if !GRPC_CORE - IDisposable, -#endif - IAsyncDisposable { + public sealed partial class EventStoreClient : EventStoreClientBase { private static readonly JsonSerializerOptions StreamMetadataJsonSerializerOptions = new() { Converters = { @@ -35,9 +30,9 @@ public partial class EventStoreClient : EventStoreClientBase, #if NET5_0_OR_GREATER private Lazy _streamAppenderLazy; private StreamAppender _streamAppender => _streamAppenderLazy.Value; + private readonly CancellationTokenSource _disposedTokenSource; #endif - private readonly CancellationTokenSource _disposedTokenSource; private static readonly Dictionary> ExceptionMap = new() { [Constants.Exceptions.InvalidTransaction] = @@ -76,8 +71,8 @@ public EventStoreClient(IOptions options) : this(optio /// public EventStoreClient(EventStoreClientSettings? settings = null) : base(settings, ExceptionMap) { _log = Settings.LoggerFactory?.CreateLogger() ?? new NullLogger(); - _disposedTokenSource = new CancellationTokenSource(); #if NET5_0_OR_GREATER + _disposedTokenSource = new CancellationTokenSource(); _streamAppenderLazy = new Lazy(CreateStreamAppender); #endif } @@ -166,22 +161,26 @@ private StreamAppender CreateStreamAppender() { return options; } -#if !GRPC_CORE - void IDisposable.Dispose() { -#if NET5_0_OR_GREATER - _streamAppender.Dispose(); -#endif +#if !GRPC_CORE && NET5_0_OR_GREATER + /// + public override void Dispose() { + _disposedTokenSource.Cancel(); + if (_streamAppenderLazy.IsValueCreated) + _streamAppenderLazy.Value.Dispose(); _disposedTokenSource.Dispose(); base.Dispose(); } #endif - async ValueTask IAsyncDisposable.DisposeAsync() { #if NET5_0_OR_GREATER - _streamAppender.Dispose(); -#endif + /// + public override async ValueTask DisposeAsync() { + _disposedTokenSource.Cancel(); _disposedTokenSource.Dispose(); + if (_streamAppenderLazy.IsValueCreated) + _streamAppenderLazy.Value.Dispose(); await base.DisposeAsync().ConfigureAwait(false); } +#endif } } diff --git a/src/EventStore.Client.UserManagement/EventStoreUserManagementClient.cs b/src/EventStore.Client.UserManagement/EventStoreUserManagementClient.cs index 85cf6535e..3dd23e9ba 100644 --- a/src/EventStore.Client.UserManagement/EventStoreUserManagementClient.cs +++ b/src/EventStore.Client.UserManagement/EventStoreUserManagementClient.cs @@ -14,7 +14,7 @@ namespace EventStore.Client { /// /// The client used for operations on internal users. /// - public class EventStoreUserManagementClient : EventStoreClientBase { + public sealed class EventStoreUserManagementClient : EventStoreClientBase { private readonly ILogger _log; /// diff --git a/src/EventStore.Client/EventStoreClientBase.cs b/src/EventStore.Client/EventStoreClientBase.cs index 427ec3790..a091d826d 100644 --- a/src/EventStore.Client/EventStoreClientBase.cs +++ b/src/EventStore.Client/EventStoreClientBase.cs @@ -98,7 +98,7 @@ private void Rediscover() { #if !GRPC_CORE /// - public void Dispose() { + public virtual void Dispose() { _cts.Cancel(); _cts.Dispose(); _channelCache.Dispose(); @@ -106,7 +106,7 @@ public void Dispose() { #endif /// - public async ValueTask DisposeAsync() { + public virtual async ValueTask DisposeAsync() { _cts.Cancel(); _cts.Dispose(); await _channelCache.DisposeAsync().ConfigureAwait(false);