From dc906e86049ee78da37883ba8801e414f90986e5 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Jun 2020 12:49:25 +0200 Subject: [PATCH] External link fix. --- .../Backup/BackupGrain.cs | 20 +++++++++++----- .../Rules/Runner/RuleRunnerGrain.cs | 24 ++++++++++++------- .../EventSourcing/RetrySubscription.cs | 10 +++++--- .../Timers/CompletionTimer.cs | 23 +++++++++++++++--- frontend/app/theme/_common.scss | 5 ---- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs index 97567f106..60434cddf 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs @@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Entities.Backup private readonly ISemanticLog log; private readonly IGrainState state; private readonly IUserResolver userResolver; - private CancellationTokenSource? currentTaskToken; + private CancellationTokenSource? currentJobToken; private BackupJob? currentJob; public BackupGrain( @@ -90,7 +90,7 @@ namespace Squidex.Domain.Apps.Entities.Backup public async Task BackupAsync(RefToken actor) { - if (currentTaskToken != null) + if (currentJobToken != null) { throw new DomainException("Another backup process is already running."); } @@ -107,14 +107,14 @@ namespace Squidex.Domain.Apps.Entities.Backup Status = JobStatus.Started }; - currentTaskToken = new CancellationTokenSource(); + currentJobToken = new CancellationTokenSource(); currentJob = job; state.Value.Jobs.Insert(0, job); await state.WriteAsync(); - Process(job, actor, currentTaskToken.Token); + Process(job, actor, currentJobToken.Token); } private void Process(BackupJob job, RefToken actor, CancellationToken ct) @@ -205,7 +205,8 @@ namespace Squidex.Domain.Apps.Entities.Backup await state.WriteAsync(); - currentTaskToken = null; + currentJobToken?.Dispose(); + currentJobToken = null; currentJob = null; } } @@ -235,7 +236,14 @@ namespace Squidex.Domain.Apps.Entities.Backup if (currentJob == job) { - currentTaskToken?.Cancel(); + try + { + currentJobToken?.Cancel(); + } + catch (ObjectDisposedException) + { + return; + } } else { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs index 81325a123..deb6ed6a9 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs @@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner private readonly IRuleEventRepository ruleEventRepository; private readonly RuleService ruleService; private readonly ISemanticLog log; - private CancellationTokenSource? currentTaskToken; + private CancellationTokenSource? currentJobToken; private IGrainReminder? currentReminder; private bool isStopping; @@ -80,14 +80,21 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner { isStopping = true; - currentTaskToken?.Cancel(); + currentJobToken?.Cancel(); return base.OnDeactivateAsync(); } public Task CancelAsync() { - currentTaskToken?.Cancel(); + try + { + currentJobToken?.Cancel(); + } + catch (ObjectDisposedException) + { + return Task.CompletedTask; + } return Task.CompletedTask; } @@ -99,7 +106,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner public async Task RunAsync(Guid ruleId) { - if (currentTaskToken != null) + if (currentJobToken != null) { throw new DomainException("Another rule is already running."); } @@ -116,11 +123,11 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner private void EnsureIsRunning() { - if (state.Value.RuleId.HasValue && currentTaskToken == null) + if (state.Value.RuleId.HasValue && currentJobToken == null) { - currentTaskToken = new CancellationTokenSource(); + currentJobToken = new CancellationTokenSource(); - Process(state.Value, currentTaskToken.Token); + Process(state.Value, currentJobToken.Token); } } @@ -187,7 +194,8 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner currentReminder = null; } - currentTaskToken = null; + currentJobToken?.Dispose(); + currentJobToken = null; } } } diff --git a/backend/src/Squidex.Infrastructure/EventSourcing/RetrySubscription.cs b/backend/src/Squidex.Infrastructure/EventSourcing/RetrySubscription.cs index 8f1c709c9..fbf66a199 100644 --- a/backend/src/Squidex.Infrastructure/EventSourcing/RetrySubscription.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/RetrySubscription.cs @@ -17,7 +17,7 @@ namespace Squidex.Infrastructure.EventSourcing public sealed class RetrySubscription : IEventSubscription, IEventSubscriber { private readonly SingleThreadedDispatcher dispatcher = new SingleThreadedDispatcher(10); - private readonly CancellationTokenSource timerCts = new CancellationTokenSource(); + private readonly CancellationTokenSource timerCancellation = new CancellationTokenSource(); private readonly RetryWindow retryWindow = new RetryWindow(TimeSpan.FromMinutes(5), 5); private readonly IEventStore eventStore; private readonly IEventSubscriber eventSubscriber; @@ -91,7 +91,7 @@ namespace Squidex.Infrastructure.EventSourcing private async Task RetryAsync() { - await Task.Delay(ReconnectWaitMs, timerCts.Token); + await Task.Delay(ReconnectWaitMs, timerCancellation.Token); await dispatcher.DispatchAsync(Subscribe); } @@ -111,7 +111,11 @@ namespace Squidex.Infrastructure.EventSourcing await dispatcher.DispatchAsync(Unsubscribe); await dispatcher.StopAndWaitAsync(); - timerCts.Cancel(); + if (!timerCancellation.IsCancellationRequested) + { + timerCancellation.Cancel(); + timerCancellation.Dispose(); + } } } } diff --git a/backend/src/Squidex.Infrastructure/Timers/CompletionTimer.cs b/backend/src/Squidex.Infrastructure/Timers/CompletionTimer.cs index 61a93f7e8..a9d052263 100644 --- a/backend/src/Squidex.Infrastructure/Timers/CompletionTimer.cs +++ b/backend/src/Squidex.Infrastructure/Timers/CompletionTimer.cs @@ -42,7 +42,14 @@ namespace Squidex.Infrastructure.Timers { Interlocked.CompareExchange(ref oneCallState, OneCallRequested, OneCallNotExecuted); - wakeupToken?.Cancel(); + try + { + wakeupToken?.Cancel(); + } + catch (ObjectDisposedException) + { + return; + } } } @@ -76,9 +83,19 @@ namespace Squidex.Infrastructure.Timers { wakeupToken = new CancellationTokenSource(); - using (var cts = CancellationTokenSource.CreateLinkedTokenSource(stopToken.Token, wakeupToken.Token)) + try + { + using (wakeupToken) + { + using (var cts = CancellationTokenSource.CreateLinkedTokenSource(stopToken.Token, wakeupToken.Token)) + { + await Task.Delay(intervall, cts.Token).ConfigureAwait(false); + } + } + } + finally { - await Task.Delay(intervall, cts.Token).ConfigureAwait(false); + wakeupToken = null; } } catch (OperationCanceledException) diff --git a/frontend/app/theme/_common.scss b/frontend/app/theme/_common.scss index 42927f4d6..9cd733bea 100644 --- a/frontend/app/theme/_common.scss +++ b/frontend/app/theme/_common.scss @@ -182,11 +182,6 @@ body { visibility: hidden; } -//External link with icon -.external { - white-space: nowrap; -} - // // Drop area for drag and drop features. //