Browse Source

Use options for jint.

pull/802/head
Sebastian 4 years ago
parent
commit
a0d587d7c0
  1. 44
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
  2. 16
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptOptions.cs
  3. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesJintExtension.cs
  4. 18
      backend/src/Squidex/Config/Domain/InfrastructureServices.cs
  5. 8
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs
  6. 8
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs
  7. 8
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs
  8. 8
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs
  9. 6
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsJintExtensionTests.cs
  10. 13
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/Guards/ScriptingExtensionsTests.cs
  11. 10
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentTriggerHandlerTests.cs
  12. 7
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Counter/CounterJintExtensionTests.cs
  13. 5
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DynamicContentWorkflowTests.cs
  14. 6
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesJintExtensionTests.cs

44
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

@ -11,6 +11,7 @@ using Jint;
using Jint.Native; using Jint.Native;
using Jint.Runtime; using Jint.Runtime;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting.ContentWrapper; using Squidex.Domain.Apps.Core.Scripting.ContentWrapper;
using Squidex.Domain.Apps.Core.Scripting.Internal; using Squidex.Domain.Apps.Core.Scripting.Internal;
@ -25,41 +26,16 @@ namespace Squidex.Domain.Apps.Core.Scripting
{ {
private readonly IJintExtension[] extensions; private readonly IJintExtension[] extensions;
private readonly Parser parser; private readonly Parser parser;
private readonly TimeSpan timeoutScript;
private readonly TimeSpan timeoutExecution;
public TimeSpan TimeoutScript { get; set; } = TimeSpan.FromMilliseconds(200); public JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOptions> options, IEnumerable<IJintExtension>? extensions = null)
public TimeSpan TimeoutExecution { get; set; } = TimeSpan.FromMilliseconds(4000);
private TimeSpan ActualTimeoutScript
{
get
{
if (Debugger.IsAttached)
{
return TimeSpan.FromHours(1);
}
return TimeoutScript;
}
}
private TimeSpan ActualTimeoutExecution
{
get
{
if (Debugger.IsAttached)
{
return TimeSpan.FromHours(1);
}
return TimeoutExecution;
}
}
public JintScriptEngine(IMemoryCache cache, IEnumerable<IJintExtension>? extensions = null)
{ {
parser = new Parser(cache); parser = new Parser(cache);
timeoutScript = options.Value.TimeoutScript;
timeoutExecution = options.Value.TimeoutExecution;
this.extensions = extensions?.ToArray() ?? Array.Empty<IJintExtension>(); this.extensions = extensions?.ToArray() ?? Array.Empty<IJintExtension>();
} }
@ -69,7 +45,7 @@ namespace Squidex.Domain.Apps.Core.Scripting
Guard.NotNull(vars, nameof(vars)); Guard.NotNull(vars, nameof(vars));
Guard.NotNullOrEmpty(script, nameof(script)); Guard.NotNullOrEmpty(script, nameof(script));
using (var cts = new CancellationTokenSource(ActualTimeoutExecution)) using (var cts = new CancellationTokenSource(timeoutExecution))
{ {
using (var combined = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct)) using (var combined = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct))
{ {
@ -107,7 +83,7 @@ namespace Squidex.Domain.Apps.Core.Scripting
Guard.NotNull(vars, nameof(vars)); Guard.NotNull(vars, nameof(vars));
Guard.NotNullOrEmpty(script, nameof(script)); Guard.NotNullOrEmpty(script, nameof(script));
using (var cts = new CancellationTokenSource(ActualTimeoutExecution)) using (var cts = new CancellationTokenSource(timeoutExecution))
{ {
using (var combined = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct)) using (var combined = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct))
{ {
@ -181,7 +157,7 @@ namespace Squidex.Domain.Apps.Core.Scripting
engineOptions.AddObjectConverter(DefaultConverter.Instance); engineOptions.AddObjectConverter(DefaultConverter.Instance);
engineOptions.SetReferencesResolver(NullPropagation.Instance); engineOptions.SetReferencesResolver(NullPropagation.Instance);
engineOptions.Strict(); engineOptions.Strict();
engineOptions.TimeoutInterval(ActualTimeoutScript); engineOptions.TimeoutInterval(timeoutScript);
}); });
if (options.CanDisallow) if (options.CanDisallow)

16
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptOptions.cs

@ -0,0 +1,16 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Domain.Apps.Core.Scripting
{
public sealed class JintScriptOptions
{
public TimeSpan TimeoutScript { get; set; } = TimeSpan.FromMilliseconds(200);
public TimeSpan TimeoutExecution { get; set; } = TimeSpan.FromMilliseconds(4000);
}
}

2
backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesJintExtension.cs

@ -95,7 +95,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(ids), context.CancellationToken); var contents = await contentQuery.QueryAsync(requestContext, Q.Empty.WithIds(ids), context.CancellationToken);
// Reset the time contraints and other constraints so that our awaiting does not count. // Reset the time contraints and other constraints so that our awaiting does not count as script time.
context.Engine.ResetConstraints(); context.Engine.ResetConstraints();
callback(JsValue.FromObject(context.Engine, contents.ToArray())); callback(JsValue.FromObject(context.Engine, contents.ToArray()));

18
backend/src/Squidex/Config/Domain/InfrastructureServices.cs

@ -47,28 +47,22 @@ namespace Squidex.Config.Domain
services.Configure<ReplicatedCacheOptions>(config, services.Configure<ReplicatedCacheOptions>(config,
"caching:replicated"); "caching:replicated");
services.Configure<JintScriptEngine>(config,
"scripting");
services.AddReplicatedCache(); services.AddReplicatedCache();
services.AddAsyncLocalCache(); services.AddAsyncLocalCache();
services.AddBackgroundCache(); services.AddBackgroundCache();
var timeoutExecution = config.GetValue<TimeSpan>("scripting:timeoutExecution");
var timeoutScript = config.GetValue<TimeSpan>("scripting:timeoutScript");
services.AddSingletonAs(c =>
new JintScriptEngine(
c.GetRequiredService<IMemoryCache>(),
c.GetRequiredService<IEnumerable<IJintExtension>>())
{
TimeoutExecution = timeoutExecution,
TimeoutScript = timeoutScript
}).As<IScriptEngine>();
services.AddSingletonAs(_ => SystemClock.Instance) services.AddSingletonAs(_ => SystemClock.Instance)
.As<IClock>(); .As<IClock>();
services.AddSingletonAs<GrainBootstrap<IEventConsumerManagerGrain>>() services.AddSingletonAs<GrainBootstrap<IEventConsumerManagerGrain>>()
.AsSelf(); .AsSelf();
services.AddSingletonAs<JintScriptEngine>()
.As<IScriptEngine>();
services.AddSingletonAs<GrainTagService>() services.AddSingletonAs<GrainTagService>()
.As<ITagService>(); .As<ITagService>();

8
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs

@ -106,13 +106,13 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
new StringWordsJintExtension() new StringWordsJintExtension()
}; };
var cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); return new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
return new JintScriptEngine(cache, extensions)
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Theory] [Theory]

8
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs

@ -96,13 +96,13 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
new StringWordsJintExtension() new StringWordsJintExtension()
}; };
var cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); return new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
return new JintScriptEngine(cache, extensions)
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Fact] [Fact]

8
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs

@ -35,13 +35,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
new StringWordsJintExtension() new StringWordsJintExtension()
}; };
var cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
sut = new JintScriptEngine(cache, extensions)
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Fact] [Fact]

8
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs

@ -52,13 +52,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
A.CallTo(() => httpClientFactory.CreateClient(A<string>._)) A.CallTo(() => httpClientFactory.CreateClient(A<string>._))
.Returns(new HttpClient(httpHandler)); .Returns(new HttpClient(httpHandler));
var cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
sut = new JintScriptEngine(cache, extensions)
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Fact] [Fact]

6
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetsJintExtensionTests.cs

@ -48,11 +48,13 @@ namespace Squidex.Domain.Apps.Entities.Assets
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false, default)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false, default))
.Returns(Mocks.App(appId)); .Returns(Mocks.App(appId));
sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())), extensions) sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Fact] [Fact]

13
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/Guards/ScriptingExtensionsTests.cs

@ -89,10 +89,19 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject.Guards
A.CallTo(() => app.AssetScripts) A.CallTo(() => app.AssetScripts)
.Returns(scripts); .Returns(scripts);
var scriptEngine = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
{
TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10)
}));
var serviceProvider = var serviceProvider =
new ServiceCollection() new ServiceCollection()
.AddSingleton<IScriptEngine>( .AddMemoryCache()
new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())))) .AddOptions()
.AddOptions<MemoryCacheOptions>().Services
.AddSingleton<IScriptEngine, JintScriptEngine>()
.BuildServiceProvider(); .BuildServiceProvider();
command.Actor = actor; command.Actor = actor;

10
backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentTriggerHandlerTests.cs

@ -265,9 +265,15 @@ namespace Squidex.Domain.Apps.Entities.Comments
Condition = condition Condition = condition
}; };
var memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions())); var realScriptEngine =
new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
{
TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10)
}));
var handler = new CommentTriggerHandler(new JintScriptEngine(memoryCache), userResolver); var handler = new CommentTriggerHandler(realScriptEngine, userResolver);
action(handler, Context(trigger)); action(handler, Context(trigger));
} }

7
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Counter/CounterJintExtensionTests.cs

@ -28,13 +28,12 @@ namespace Squidex.Domain.Apps.Entities.Contents.Counter
new CounterJintExtension(grainFactory) new CounterJintExtension(grainFactory)
}; };
var cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
sut = new JintScriptEngine(cache, extensions)
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }), extensions);
} }
[Fact] [Fact]

5
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DynamicContentWorkflowTests.cs

@ -90,11 +90,12 @@ namespace Squidex.Domain.Apps.Entities.Contents
A.CallTo(() => app.Workflows) A.CallTo(() => app.Workflows)
.Returns(workflows); .Returns(workflows);
var scriptEngine = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions()))) var scriptEngine = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }));
sut = new DynamicContentWorkflow(scriptEngine, appProvider); sut = new DynamicContentWorkflow(scriptEngine, appProvider);
} }

6
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ReferencesJintExtensionTests.cs

@ -43,11 +43,13 @@ namespace Squidex.Domain.Apps.Entities.Contents
A.CallTo(() => appProvider.GetAppAsync(appId.Id, false, default)) A.CallTo(() => appProvider.GetAppAsync(appId.Id, false, default))
.Returns(Mocks.App(appId)); .Returns(Mocks.App(appId));
sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())), extensions) sut = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
Options.Create(new JintScriptOptions
{ {
TimeoutScript = TimeSpan.FromSeconds(2), TimeoutScript = TimeSpan.FromSeconds(2),
TimeoutExecution = TimeSpan.FromSeconds(10) TimeoutExecution = TimeSpan.FromSeconds(10)
}; }),
extensions);
} }
[Fact] [Fact]

Loading…
Cancel
Save