From a282cc5691c19ea39d4429e31626d1c5413c77e7 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 12 Feb 2025 08:06:50 +0100 Subject: [PATCH] Backport use of thread delay over sleep and handle dispose in FileSystemMainDomLock (#18151) * Backport use of thread delay over sleep and handle dispose in FileSystemMainDomLock (from PRs #18119 and #18147) * Applied suggestion from code review. --- .../Runtime/FileSystemMainDomLock.cs | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs index 6dcd3ef9b0..27662f979a 100644 --- a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs +++ b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs @@ -15,6 +15,7 @@ internal class FileSystemMainDomLock : IMainDomLock private readonly string _lockFilePath; private readonly ILogger _logger; private readonly string _releaseSignalFilePath; + private bool _disposed; private Task? _listenForReleaseSignalFileTask; private FileStream? _lockFileStream; @@ -88,16 +89,14 @@ internal class FileSystemMainDomLock : IMainDomLock ListeningLoop, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, - TaskScheduler.Default); + TaskScheduler.Default) + .Unwrap(); // Because ListeningLoop is an async method, we need to use Unwrap to return the inner task. return _listenForReleaseSignalFileTask; } - public void Dispose() - { - _lockFileStream?.Close(); - _lockFileStream = null; - } + /// Releases the resources used by this . + public void Dispose() => Dispose(true); public void CreateLockReleaseSignalFile() => File.Open(_releaseSignalFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, @@ -107,7 +106,27 @@ internal class FileSystemMainDomLock : IMainDomLock public void DeleteLockReleaseSignalFile() => File.Delete(_releaseSignalFilePath); - private void ListeningLoop() + /// Releases the resources used by this . + /// true to release both managed resources. + protected virtual void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + _logger.LogInformation($"{nameof(FileSystemMainDomLock)} Disposing..."); + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + ReleaseLock(); + _disposed = true; + } + } + + private void ReleaseLock() + { + _lockFileStream?.Close(); + _lockFileStream = null; + } + + private async Task ListeningLoop() { while (true) { @@ -126,12 +145,12 @@ internal class FileSystemMainDomLock : IMainDomLock { _logger.LogDebug("Found lock release signal file, releasing lock on {lockFilePath}", _lockFilePath); } - _lockFileStream?.Close(); - _lockFileStream = null; + + ReleaseLock(); break; } - Thread.Sleep(_globalSettings.CurrentValue.MainDomReleaseSignalPollingInterval); + await Task.Delay(_globalSettings.CurrentValue.MainDomReleaseSignalPollingInterval, _cancellationTokenSource.Token); } } }