Browse Source

changes to use dispose

Luke Brown 3 years ago
parent
commit
a64eebe79f

+ 0 - 6
Emby.Dlna/PlayTo/PlayToController.cs

@@ -889,12 +889,6 @@ namespace Emby.Dlna.PlayTo
             return Task.CompletedTask;
         }
 
-        /// <inheritdoc />
-        public Task CloseAllWebSockets(CancellationToken cancellationToken)
-        {
-            return Task.CompletedTask;
-        }
-
         private class StreamParams
         {
             private MediaSourceInfo _mediaSource;

+ 20 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -111,7 +111,7 @@ namespace Emby.Server.Implementations
     /// <summary>
     /// Class CompositionRoot.
     /// </summary>
-    public abstract class ApplicationHost : IServerApplicationHost, IDisposable
+    public abstract class ApplicationHost : IServerApplicationHost, IAsyncDisposable, IDisposable
     {
         /// <summary>
         /// The environment variable prefixes to log at server startup.
@@ -1230,5 +1230,24 @@ namespace Emby.Server.Implementations
 
             _disposed = true;
         }
+
+        public async ValueTask DisposeAsync()
+        {
+            await DisposeAsyncCore().ConfigureAwait(false);
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Used to perform asynchronous cleanup of managed resources or for cascading calls to <see cref="DisposeAsync"/>.
+        /// </summary>
+        /// <returns>A ValueTask.</returns>
+        protected virtual async ValueTask DisposeAsyncCore()
+        {
+            foreach (var session in _sessionManager.Sessions)
+            {
+                await session.DisposeAsync().ConfigureAwait(false);
+            }
+        }
     }
 }

+ 21 - 7
Emby.Server.Implementations/HttpServer/WebSocketConnection.cs

@@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.HttpServer
     /// <summary>
     /// Class WebSocketConnection.
     /// </summary>
-    public class WebSocketConnection : IWebSocketConnection, IDisposable
+    public class WebSocketConnection : IWebSocketConnection, IAsyncDisposable, IDisposable
     {
         /// <summary>
         /// The logger.
@@ -231,12 +231,6 @@ namespace Emby.Server.Implementations.HttpServer
                 CancellationToken.None);
         }
 
-        /// <inheritdoc />
-        public async Task CloseSocket(CancellationToken cancellationToken)
-        {
-            await _socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "System Shutdown", cancellationToken).ConfigureAwait(false);
-        }
-
         /// <inheritdoc />
         public void Dispose()
         {
@@ -255,5 +249,25 @@ namespace Emby.Server.Implementations.HttpServer
                 _socket.Dispose();
             }
         }
+
+        /// <inheritdoc />
+        public async ValueTask DisposeAsync()
+        {
+            await DisposeAsyncCore().ConfigureAwait(false);
+            Dispose(false);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Used to perform asynchronous cleanup of managed resources or for cascading calls to <see cref="DisposeAsync"/>.
+        /// </summary>
+        /// <returns>A ValueTask.</returns>
+        protected virtual async ValueTask DisposeAsyncCore()
+        {
+            if (_socket.State == WebSocketState.Open)
+            {
+                await _socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "System Shutdown", CancellationToken.None).ConfigureAwait(false);
+            }
+        }
     }
 }

+ 0 - 17
Emby.Server.Implementations/Session/SessionManager.cs

@@ -1363,26 +1363,9 @@ namespace Emby.Server.Implementations.Session
         {
             CheckDisposed();
 
-            await CloseAllWebSockets(cancellationToken).ConfigureAwait(false);
-
             await SendMessageToSessions(Sessions, SessionMessageType.ServerShuttingDown, string.Empty, cancellationToken).ConfigureAwait(false);
         }
 
-        /// <summary>
-        /// Gracefully closes all web sockets in all sessions.
-        /// </summary>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        private async Task CloseAllWebSockets(CancellationToken cancellationToken)
-        {
-            foreach (var session in Sessions)
-            {
-                foreach (var sessionController in session.SessionControllers)
-                {
-                    await sessionController.CloseAllWebSockets(cancellationToken).ConfigureAwait(false);
-                }
-            }
-        }
-
         /// <summary>
         /// Sends the server restart notification.
         /// </summary>

+ 16 - 5
Emby.Server.Implementations/Session/WebSocketController.cs

@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.Session
 {
-    public sealed class WebSocketController : ISessionController, IDisposable
+    public sealed class WebSocketController : ISessionController, IAsyncDisposable, IDisposable
     {
         private readonly ILogger<WebSocketController> _logger;
         private readonly ISessionManager _sessionManager;
@@ -89,16 +89,22 @@ namespace Emby.Server.Implementations.Session
         }
 
         /// <inheritdoc />
-        public async Task CloseAllWebSockets(CancellationToken cancellationToken)
+        public void Dispose()
         {
+            if (_disposed)
+            {
+                return;
+            }
+
             foreach (var socket in _sockets)
             {
-                await socket.CloseSocket(cancellationToken).ConfigureAwait(false);
+                socket.Closed -= OnConnectionClosed;
             }
+
+            _disposed = true;
         }
 
-        /// <inheritdoc />
-        public void Dispose()
+        public async ValueTask DisposeAsync()
         {
             if (_disposed)
             {
@@ -108,6 +114,11 @@ namespace Emby.Server.Implementations.Session
             foreach (var socket in _sockets)
             {
                 socket.Closed -= OnConnectionClosed;
+
+                if (socket is IAsyncDisposable disposableAsync)
+                {
+                    await disposableAsync.DisposeAsync().ConfigureAwait(false);
+                }
             }
 
             _disposed = true;

+ 1 - 1
Jellyfin.Server/Program.cs

@@ -243,7 +243,7 @@ namespace Jellyfin.Server
                     }
                 }
 
-                appHost.Dispose();
+                await appHost.DisposeAsync().ConfigureAwait(false);
             }
 
             if (_restartOnShutdown)

+ 0 - 7
MediaBrowser.Controller/Net/IWebSocketConnection.cs

@@ -58,12 +58,5 @@ namespace MediaBrowser.Controller.Net
         Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken);
 
         Task ProcessAsync(CancellationToken cancellationToken = default);
-
-        /// <summary>
-        /// Gracefully closes the socket.
-        /// </summary>
-        /// <returns>Task.</returns>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        Task CloseSocket(CancellationToken cancellationToken);
     }
 }

+ 0 - 7
MediaBrowser.Controller/Session/ISessionController.cs

@@ -33,12 +33,5 @@ namespace MediaBrowser.Controller.Session
         /// <param name="cancellationToken">CancellationToken for operation.</param>
         /// <returns>A task.</returns>
         Task SendMessage<T>(SessionMessageType name, Guid messageId, T data, CancellationToken cancellationToken);
-
-        /// <summary>
-        /// Gracefully closes all web sockets.
-        /// </summary>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>A task.</returns>
-        Task CloseAllWebSockets(CancellationToken cancellationToken);
     }
 }

+ 21 - 2
MediaBrowser.Controller/Session/SessionInfo.cs

@@ -7,6 +7,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text.Json.Serialization;
 using System.Threading;
+using System.Threading.Tasks;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Session;
@@ -17,7 +18,7 @@ namespace MediaBrowser.Controller.Session
     /// <summary>
     /// Class SessionInfo.
     /// </summary>
-    public sealed class SessionInfo : IDisposable
+    public sealed class SessionInfo : IAsyncDisposable, IDisposable
     {
         // 1 second
         private const long ProgressIncrement = 10000000;
@@ -380,10 +381,28 @@ namespace MediaBrowser.Controller.Session
             {
                 if (controller is IDisposable disposable)
                 {
-                    _logger.LogDebug("Disposing session controller {0}", disposable.GetType().Name);
+                    _logger.LogInformation("Disposing session controller synchronously {0}", disposable.GetType().Name);
                     disposable.Dispose();
                 }
             }
         }
+
+        public async ValueTask DisposeAsync()
+        {
+            _disposed = true;
+
+            StopAutomaticProgress();
+
+            var controllers = SessionControllers.ToList();
+
+            foreach (var controller in controllers)
+            {
+                if (controller is IAsyncDisposable disposableAsync)
+                {
+                    _logger.LogInformation("Disposing session controller asynchronously {0}", disposableAsync.GetType().Name);
+                    await disposableAsync.DisposeAsync().ConfigureAwait(false);
+                }
+            }
+        }
     }
 }