Browse Source

Make execution timeout for rules configurable.

pull/408/head
Sebastian Stehle 7 years ago
parent
commit
4badcf0c41
  1. 14
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleOptions.cs
  2. 15
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
  3. 3
      src/Squidex/WebStartup.cs
  4. 7
      src/Squidex/appsettings.json
  5. 6
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs

14
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleOptions.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Domain.Apps.Core.HandleRules
{
public sealed class RuleOptions
{
public int ExecutionTimeoutInSeconds { get; set; } = 3;
}
}

15
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events;
@ -23,16 +24,17 @@ namespace Squidex.Domain.Apps.Core.HandleRules
{ {
public class RuleService public class RuleService
{ {
private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(3);
private readonly Dictionary<Type, IRuleActionHandler> ruleActionHandlers; private readonly Dictionary<Type, IRuleActionHandler> ruleActionHandlers;
private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers; private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers;
private readonly TypeNameRegistry typeNameRegistry; private readonly TypeNameRegistry typeNameRegistry;
private readonly RuleOptions ruleOptions;
private readonly IEventEnricher eventEnricher; private readonly IEventEnricher eventEnricher;
private readonly IJsonSerializer jsonSerializer; private readonly IJsonSerializer jsonSerializer;
private readonly IClock clock; private readonly IClock clock;
private readonly ISemanticLog log; private readonly ISemanticLog log;
public RuleService( public RuleService(
IOptions<RuleOptions> ruleOptions,
IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers, IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers,
IEnumerable<IRuleActionHandler> ruleActionHandlers, IEnumerable<IRuleActionHandler> ruleActionHandlers,
IEventEnricher eventEnricher, IEventEnricher eventEnricher,
@ -42,6 +44,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
TypeNameRegistry typeNameRegistry) TypeNameRegistry typeNameRegistry)
{ {
Guard.NotNull(jsonSerializer, nameof(jsonSerializer)); Guard.NotNull(jsonSerializer, nameof(jsonSerializer));
Guard.NotNull(ruleOptions, nameof(ruleOptions));
Guard.NotNull(ruleTriggerHandlers, nameof(ruleTriggerHandlers)); Guard.NotNull(ruleTriggerHandlers, nameof(ruleTriggerHandlers));
Guard.NotNull(ruleActionHandlers, nameof(ruleActionHandlers)); Guard.NotNull(ruleActionHandlers, nameof(ruleActionHandlers));
Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry)); Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry));
@ -51,14 +54,15 @@ namespace Squidex.Domain.Apps.Core.HandleRules
this.typeNameRegistry = typeNameRegistry; this.typeNameRegistry = typeNameRegistry;
this.ruleOptions = ruleOptions.Value;
this.ruleTriggerHandlers = ruleTriggerHandlers.ToDictionary(x => x.TriggerType); this.ruleTriggerHandlers = ruleTriggerHandlers.ToDictionary(x => x.TriggerType);
this.ruleActionHandlers = ruleActionHandlers.ToDictionary(x => x.ActionType); this.ruleActionHandlers = ruleActionHandlers.ToDictionary(x => x.ActionType);
this.eventEnricher = eventEnricher; this.eventEnricher = eventEnricher;
this.jsonSerializer = jsonSerializer; this.jsonSerializer = jsonSerializer;
this.clock = clock; this.clock = clock;
this.log = log; this.log = log;
} }
@ -171,7 +175,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
var deserialized = jsonSerializer.Deserialize<object>(job, actionHandler.DataType); var deserialized = jsonSerializer.Deserialize<object>(job, actionHandler.DataType);
using (var cts = new CancellationTokenSource(DefaultTimeout)) using (var cts = new CancellationTokenSource(GetTimeoutInMs()))
{ {
result = await actionHandler.ExecuteJobAsync(deserialized, cts.Token).WithCancellation(cts.Token); result = await actionHandler.ExecuteJobAsync(deserialized, cts.Token).WithCancellation(cts.Token);
} }
@ -187,5 +191,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return (result, elapsed); return (result, elapsed);
} }
private int GetTimeoutInMs()
{
return ruleOptions.ExecutionTimeoutInSeconds * 1000;
}
} }
} }

3
src/Squidex/WebStartup.cs

@ -27,6 +27,7 @@ using Squidex.Config.Domain;
using Squidex.Config.Orleans; using Squidex.Config.Orleans;
using Squidex.Config.Startup; using Squidex.Config.Startup;
using Squidex.Config.Web; using Squidex.Config.Web;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -100,6 +101,8 @@ namespace Squidex
config.GetSection("rebuild")); config.GetSection("rebuild"));
services.Configure<ExposedConfiguration>( services.Configure<ExposedConfiguration>(
config.GetSection("exposedConfiguration")); config.GetSection("exposedConfiguration"));
services.Configure<RuleOptions>(
config.GetSection("rules"));
services.Configure<MyContentsControllerOptions>( services.Configure<MyContentsControllerOptions>(
config.GetSection("contentsController")); config.GetSection("contentsController"));

7
src/Squidex/appsettings.json

@ -39,6 +39,13 @@
"custom": "" "custom": ""
}, },
"rules": {
/*
* The timeout to execute rule actions.
*/
"executionTimeoutInSeconds": 3
},
"ui": { "ui": {
/* /*
* Regex suggestions for the UI * Regex suggestions for the UI

6
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs

@ -9,6 +9,7 @@ using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Microsoft.Extensions.Options;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
@ -84,7 +85,10 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
var log = A.Fake<ISemanticLog>(); var log = A.Fake<ISemanticLog>();
sut = new RuleService(new[] { ruleTriggerHandler }, new[] { ruleActionHandler }, eventEnricher, TestUtils.DefaultSerializer, clock, log, typeNameRegistry); sut = new RuleService(Options.Create(new RuleOptions()),
new[] { ruleTriggerHandler },
new[] { ruleActionHandler },
eventEnricher, TestUtils.DefaultSerializer, clock, log, typeNameRegistry);
} }
[Fact] [Fact]

Loading…
Cancel
Save