-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add execute script V2 using ClearScript + V8 with HTTP request …
…and context access (#210) * feat: add execute script V2 with HTTP and context access * style: code style * test: add recursion benchmark test * test: add arrow function tests * style: code style * style: code style * test: add regex and array test case * style: code style * feat: add loggers for context and trace on request body error
- Loading branch information
1 parent
ca8a46b
commit 3b29656
Showing
30 changed files
with
3,075 additions
and
5 deletions.
There are no files selected for viewing
141 changes: 141 additions & 0 deletions
141
src/Take.Blip.Builder.Benchmark/Actions/ExecuteScriptBenchmarkTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using BenchmarkDotNet.Attributes; | ||
using BenchmarkDotNet.Order; | ||
using NSubstitute; | ||
using Serilog; | ||
using Take.Blip.Builder.Actions.ExecuteScript; | ||
using Take.Blip.Builder.Actions.ExecuteScriptV2; | ||
using Take.Blip.Builder.Benchmark.Context; | ||
using Take.Blip.Builder.Hosting; | ||
using Take.Blip.Builder.Utils; | ||
|
||
namespace Take.Blip.Builder.Benchmark.Actions | ||
{ | ||
/// <inheritdoc /> | ||
[MemoryDiagnoser] | ||
[Orderer(SummaryOrderPolicy.FastestToSlowest)] | ||
public class ExecuteScriptBenchmarkTests : ActionTestsBase | ||
{ | ||
private ExecuteScriptV2Action _v2Action; | ||
private ExecuteScriptAction _v1Action; | ||
|
||
/// <summary> | ||
/// Setup the benchmark tests. | ||
/// </summary> | ||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
var configuration = new TestConfiguration(); | ||
var conventions = new ConventionsConfiguration(); | ||
|
||
configuration.ExecuteScriptV2Timeout = TimeSpan.FromMilliseconds(300); | ||
configuration.ExecuteScriptV2MaxRuntimeHeapSize = | ||
conventions.ExecuteScriptV2MaxRuntimeHeapSize; | ||
configuration.ExecuteScriptV2MaxRuntimeStackUsage = | ||
conventions.ExecuteScriptV2MaxRuntimeStackUsage; | ||
|
||
configuration.ExecuteScriptTimeout = TimeSpan.FromMilliseconds(300); | ||
configuration.ExecuteScriptLimitMemory = conventions.ExecuteScriptLimitMemory; | ||
configuration.ExecuteScriptLimitRecursion = 100000; | ||
configuration.ExecuteScriptMaxStatements = 0; | ||
|
||
_v2Action = new ExecuteScriptV2Action(configuration, Substitute.For<IHttpClient>(), | ||
Substitute.For<ILogger>()); | ||
|
||
_v1Action = new ExecuteScriptAction(configuration, Substitute.For<ILogger>()); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a loop script using the V1 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV1LoopScript() | ||
{ | ||
await _v1Action.ExecuteAsync(Context, Settings._v1LoopSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a loop script using the V2 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV2LoopScript() | ||
{ | ||
await _v2Action.ExecuteAsync(Context, Settings._v2LoopSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a math script using the V1 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV1MathScript() | ||
{ | ||
await _v1Action.ExecuteAsync(Context, Settings._v1MathSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a math script using the V2 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV2MathScript() | ||
{ | ||
await _v2Action.ExecuteAsync(Context, Settings._v2MathSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a json script using the V1 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV1JsonScript() | ||
{ | ||
await _v1Action.ExecuteAsync(Context, Settings._v1JsonSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a json script using the V2 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV2JsonScript() | ||
{ | ||
await _v2Action.ExecuteAsync(Context, Settings._v2JsonSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a simple script using the V1 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV1SimpleScript() | ||
{ | ||
await _v1Action.ExecuteAsync(Context, Settings._v1SimpleSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a simple script using the V2 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV2SimpleScript() | ||
{ | ||
await _v2Action.ExecuteAsync(Context, Settings._v2SimpleSettings, CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a recursion loop script using the V1 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV1RecursionLoopScript() | ||
{ | ||
await _v1Action.ExecuteAsync(Context, Settings._v1RecursionLoopSettings, | ||
CancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Execute a recursion loop script using the V2 action. | ||
/// </summary> | ||
[Benchmark] | ||
public async Task ExecuteScriptV2RecursionLoopScript() | ||
{ | ||
await _v2Action.ExecuteAsync(Context, Settings._v2RecursionLoopSettings, | ||
CancellationToken); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
using Newtonsoft.Json.Linq; | ||
using Take.Blip.Builder.Actions.ExecuteScript; | ||
using Take.Blip.Builder.Actions.ExecuteScriptV2; | ||
|
||
namespace Take.Blip.Builder.Benchmark.Actions; | ||
|
||
internal static class Settings | ||
{ | ||
private const string SIMPLE_SCRIPT = """ | ||
function run() { | ||
return 'a'; | ||
} | ||
"""; | ||
|
||
private const string LOOP_SCRIPT = """ | ||
function run() { | ||
let a = 0; | ||
while (a < 1000) { | ||
a++; | ||
} | ||
return a; | ||
} | ||
"""; | ||
|
||
private const string RECURSION_LOOP_SCRIPT = """ | ||
function recursiveLoop(a) { | ||
if (a < 1000) { | ||
return recursiveLoop(a + 1); | ||
} | ||
return a; | ||
} | ||
function run() { | ||
return recursiveLoop(0); | ||
} | ||
"""; | ||
|
||
private const string JSON_SCRIPT = """ | ||
function run() { | ||
const json = { 'a': 1, 'b': 'c', 'd' : ['1', '2'], 'e': { 'f': 1 } }; | ||
let stringJson = JSON.stringify(json); | ||
let parsedJson = JSON.parse(stringJson); | ||
return parsedJson.a + parsedJson.e.f; | ||
} | ||
"""; | ||
|
||
private const string MATH_SCRIPT = """ | ||
function add(a, b) { | ||
return a + b; | ||
} | ||
function subtract(a, b) { | ||
return a - b; | ||
} | ||
function multiply(a, b) { | ||
return a * b; | ||
} | ||
function divide(a, b) { | ||
if (b == 0) { | ||
throw 'Division by zero'; | ||
} | ||
return a / b; | ||
} | ||
function calculate(a, b) { | ||
let sum = add(a, b); | ||
let difference = subtract(a, b); | ||
let product = multiply(a, b); | ||
let quotient = divide(a, b); | ||
return { | ||
'sum': sum, | ||
'difference': difference, | ||
'product': product, | ||
'quotient': quotient | ||
}; | ||
} | ||
function run() { | ||
let a = 10; | ||
let b = 2; | ||
let result = calculate(a, b); | ||
let finalResult = result.sum * result.difference / result.quotient; | ||
return finalResult; | ||
} | ||
"""; | ||
|
||
internal static readonly JObject _v1LoopSettings = JObject.FromObject( | ||
new ExecuteScriptSettings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = LOOP_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v2LoopSettings = JObject.FromObject( | ||
new ExecuteScriptV2Settings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = LOOP_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v1MathSettings = JObject.FromObject( | ||
new ExecuteScriptSettings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = MATH_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v2MathSettings = JObject.FromObject( | ||
new ExecuteScriptV2Settings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = MATH_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v1JsonSettings = JObject.FromObject( | ||
new ExecuteScriptSettings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = JSON_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v2JsonSettings = JObject.FromObject( | ||
new ExecuteScriptV2Settings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = JSON_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v1SimpleSettings = JObject.FromObject( | ||
new ExecuteScriptSettings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = SIMPLE_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v2SimpleSettings = JObject.FromObject( | ||
new ExecuteScriptV2Settings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = SIMPLE_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v1RecursionLoopSettings = JObject.FromObject( | ||
new ExecuteScriptSettings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = RECURSION_LOOP_SCRIPT | ||
}); | ||
|
||
internal static readonly JObject _v2RecursionLoopSettings = JObject.FromObject( | ||
new ExecuteScriptV2Settings | ||
{ | ||
OutputVariable = "result", Function = "run", Source = RECURSION_LOOP_SCRIPT | ||
}); | ||
} |
32 changes: 32 additions & 0 deletions
32
src/Take.Blip.Builder.Benchmark/Actions/TestConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
using Take.Blip.Builder.Hosting; | ||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||
|
||
namespace Take.Blip.Builder.Benchmark.Actions | ||
{ | ||
/// <inheritdoc /> | ||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] | ||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")] | ||
public class TestConfiguration : IConfiguration | ||
{ | ||
public TimeSpan InputProcessingTimeout { get; set; } | ||
public int RedisDatabase { get; set; } | ||
public string RedisKeyPrefix { get; set; } | ||
public string InternalUris { get; set; } | ||
public int MaxTransitionsByInput { get; set; } | ||
public int TraceQueueBoundedCapacity { get; set; } | ||
public int TraceQueueMaxDegreeOfParallelism { get; set; } | ||
public TimeSpan TraceTimeout { get; set; } | ||
public TimeSpan DefaultActionExecutionTimeout { get; set; } | ||
public int ExecuteScriptLimitRecursion { get; set; } | ||
public int ExecuteScriptMaxStatements { get; set; } | ||
public long ExecuteScriptLimitMemory { get; set; } | ||
public long ExecuteScriptLimitMemoryWarning { get; set; } | ||
public TimeSpan ExecuteScriptTimeout { get; set; } | ||
public TimeSpan ExecuteScriptV2Timeout { get; set; } | ||
public int MaximumInputExpirationLoop { get; set; } | ||
public long ExecuteScriptV2MaxRuntimeHeapSize { get; set; } | ||
public long ExecuteScriptV2MaxRuntimeStackUsage { get; set; } | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/Take.Blip.Builder.Benchmark/Context/ActionTestsBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using Lime.Messaging.Contents; | ||
using Lime.Protocol; | ||
using Lime.Protocol.Serialization; | ||
using Lime.Protocol.Serialization.Newtonsoft; | ||
using NSubstitute; | ||
using Take.Blip.Builder.Models; | ||
|
||
namespace Take.Blip.Builder.Benchmark.Context; | ||
|
||
/// <inheritdoc /> | ||
public class ActionTestsBase : ContextTestsBase | ||
{ | ||
/// <inheritdoc /> | ||
protected ActionTestsBase() | ||
{ | ||
Context.Flow.Returns(Flow); | ||
From = UserIdentity.ToNode(); | ||
To = OwnerIdentity.ToNode(); | ||
Message = new Message() | ||
{ | ||
From = From, To = To, Content = new PlainText { Text = "Hello BLiP" } | ||
}; | ||
Input = new LazyInput( | ||
Message, | ||
UserIdentity, | ||
new BuilderConfiguration(), | ||
new DocumentSerializer(new DocumentTypeResolver()), | ||
new EnvelopeSerializer(new DocumentTypeResolver()), | ||
null, | ||
CancellationToken); | ||
Context.Input.Returns(Input); | ||
Context.OwnerIdentity.Returns(OwnerIdentity); | ||
Context.UserIdentity.Returns(UserIdentity); | ||
} | ||
|
||
private Node From { get; } | ||
|
||
private Node To { get; } | ||
|
||
private Message Message { get; } | ||
|
||
private LazyInput Input { get; } | ||
} |
Oops, something went wrong.