Browse Source
Fix resolve async promise timeout issue in Jint from 4.1.0 to 4.4.1 (#1250)
pull/1254/head
Noah
9 months ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with
41 additions and
2 deletions
-
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs
-
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
-
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptOptions.cs
-
backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
-
backend/src/Squidex/appsettings.json
-
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs
|
|
|
@ -109,6 +109,11 @@ public static class JsonMapper |
|
|
|
return number; |
|
|
|
} |
|
|
|
|
|
|
|
if (value.IsPromise()) |
|
|
|
{ |
|
|
|
return Map(value.UnwrapIfPromise()); |
|
|
|
} |
|
|
|
|
|
|
|
if (value is JsArray a) |
|
|
|
{ |
|
|
|
var result = new JsonArray((int)a.Length); |
|
|
|
|
|
|
|
@ -29,6 +29,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti |
|
|
|
private readonly CacheParser parser = new CacheParser(cache); |
|
|
|
private readonly TimeSpan timeoutScript = options.Value.TimeoutScript; |
|
|
|
private readonly TimeSpan timeoutExecution = options.Value.TimeoutExecution; |
|
|
|
private readonly TimeSpan timeoutPromise = options.Value.TimeoutPromise; |
|
|
|
|
|
|
|
public async Task<JsonValue> ExecuteAsync(ScriptVars vars, string script, ScriptOptions options = default, |
|
|
|
CancellationToken ct = default) |
|
|
|
@ -150,6 +151,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti |
|
|
|
|
|
|
|
if (!Debugger.IsAttached) |
|
|
|
{ |
|
|
|
engineOptions.Constraints.PromiseTimeout = timeoutPromise; |
|
|
|
engineOptions.TimeoutInterval(timeoutScript); |
|
|
|
engineOptions.CancellationToken(ct); |
|
|
|
} |
|
|
|
|
|
|
|
@ -12,4 +12,6 @@ public sealed class JintScriptOptions |
|
|
|
public TimeSpan TimeoutScript { get; set; } = TimeSpan.FromMilliseconds(200); |
|
|
|
|
|
|
|
public TimeSpan TimeoutExecution { get; set; } = TimeSpan.FromMilliseconds(4000); |
|
|
|
|
|
|
|
public TimeSpan TimeoutPromise { get; set; } = TimeSpan.FromMilliseconds(4000); |
|
|
|
} |
|
|
|
|
|
|
|
@ -20,7 +20,7 @@ |
|
|
|
<ItemGroup> |
|
|
|
<PackageReference Include="Fluid.Core" Version="2.12.0" /> |
|
|
|
<PackageReference Include="GeoJSON.Net" Version="1.4.1" /> |
|
|
|
<PackageReference Include="Jint" Version="4.1.0" /> |
|
|
|
<PackageReference Include="Jint" Version="4.4.1" /> |
|
|
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179"> |
|
|
|
<PrivateAssets>all</PrivateAssets> |
|
|
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
|
|
|
|
|
|
|
@ -126,7 +126,10 @@ |
|
|
|
"timeoutExecution": "00:00:04", |
|
|
|
|
|
|
|
// The timeout for the synchronous part of the script. |
|
|
|
"timeoutScript": "00:00:00.200" |
|
|
|
"timeoutScript": "00:00:00.200", |
|
|
|
|
|
|
|
// The timeout for the asynchronous promise of the script. |
|
|
|
"timeoutPromise": "00:00:04" |
|
|
|
}, |
|
|
|
|
|
|
|
"languages": { |
|
|
|
|
|
|
|
@ -59,6 +59,7 @@ public class JintScriptEngineTests : IClassFixture<TranslationsFixture> |
|
|
|
{ |
|
|
|
TimeoutScript = TimeSpan.FromSeconds(2), |
|
|
|
TimeoutExecution = TimeSpan.FromSeconds(10), |
|
|
|
TimeoutPromise = TimeSpan.FromSeconds(8), |
|
|
|
}), |
|
|
|
extensions); |
|
|
|
} |
|
|
|
@ -723,4 +724,30 @@ public class JintScriptEngineTests : IClassFixture<TranslationsFixture> |
|
|
|
|
|
|
|
Assert.Equal(42.0, result.Value); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_run_with_blocking_timeout_promises() |
|
|
|
{ |
|
|
|
const string script = @"
|
|
|
|
function promiseMethod() { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
setTimeout(() => { |
|
|
|
resolve(); |
|
|
|
}, 1000) |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// Jint 4.1.0 blocking (if you remove 'async', the timeout will not occur.)
|
|
|
|
async function asyncMethod() { |
|
|
|
return promiseMethod(); |
|
|
|
} |
|
|
|
|
|
|
|
(async () => { |
|
|
|
await asyncMethod(); |
|
|
|
complete() |
|
|
|
})() |
|
|
|
";
|
|
|
|
|
|
|
|
await Assert.ThrowsAsync<ValidationException>(() => sut.ExecuteAsync(new ScriptVars(), script)); |
|
|
|
} |
|
|
|
} |
|
|
|
|