perf(site-runtime): AlarmActor trigger expressions evaluate on the script scheduler (P1)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using Akka.Actor;
|
||||
using Akka.TestKit;
|
||||
using Akka.TestKit.Xunit2;
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Streaming;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
@@ -1008,4 +1010,48 @@ public class AlarmActorTests : TestKit, IDisposable
|
||||
|
||||
instanceProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
|
||||
}
|
||||
|
||||
// ── P1: Expression-alarm evaluation runs off the dispatcher ──
|
||||
|
||||
/// <summary>
|
||||
/// Compiles a trigger expression WITHOUT the trust validator so a test can use
|
||||
/// <c>System.Threading.Thread</c> to observe which thread the evaluation runs on.
|
||||
/// </summary>
|
||||
private static Script<object?> CompileRawTriggerExpression(string expression)
|
||||
{
|
||||
var opts = ScriptOptions.Default
|
||||
.WithReferences(typeof(object).Assembly, typeof(Enumerable).Assembly)
|
||||
.WithImports("System", "System.Collections.Generic", "System.Linq", "System.Threading.Tasks");
|
||||
var s = CSharpScript.Create<object?>(expression, opts, typeof(TriggerExpressionGlobals));
|
||||
s.Compile();
|
||||
return s;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExpressionAlarm_EvaluatesOnSchedulerThread_AndActivates()
|
||||
{
|
||||
// TRUE only when evaluated on a script-execution thread. Before P1 the
|
||||
// expression ran on the actor dispatcher (name is NOT "script-execution-*")
|
||||
// → false → alarm never activates. After P1 it runs on the script scheduler.
|
||||
var expr = CompileRawTriggerExpression(
|
||||
"System.Threading.Thread.CurrentThread.Name != null && " +
|
||||
"System.Threading.Thread.CurrentThread.Name.StartsWith(\"script-execution-\")");
|
||||
var alarmConfig = new ResolvedAlarm
|
||||
{
|
||||
CanonicalName = "ExprAlarm",
|
||||
TriggerType = "Expression",
|
||||
TriggerConfiguration = "{\"expression\":\"true\"}",
|
||||
PriorityLevel = 1
|
||||
};
|
||||
var instanceProbe = CreateTestProbe();
|
||||
var alarm = ActorOf(Props.Create(() => new AlarmActor(
|
||||
"ExprAlarm", "Pump1", instanceProbe.Ref, alarmConfig,
|
||||
null, _sharedLibrary, _options,
|
||||
NullLogger<AlarmActor>.Instance, expr)));
|
||||
|
||||
alarm.Tell(new AttributeValueChanged("Pump1", "A", "A", 1, "Good", DateTimeOffset.UtcNow));
|
||||
|
||||
var change = instanceProbe.ExpectMsg<AlarmStateChanged>(TimeSpan.FromSeconds(10));
|
||||
Assert.Equal(AlarmState.Active, change.State);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user