Files
richard-churchman bc66cd80e3 Expanded Inline Script Invocation Coverage and Implemented Activation Rule Chaining
* Updated documentation to include Inline Script events and Activation Rule Chaining concepts.
* Included Activation Rules in Activation Completions to make them available.
* Modified activation rule signatures to include match keys for facilitation.
* Updated Gateway Rule Priority to support double type, including changes in migrations and POCOs.
* Updated tree to ensure entities are listed by Priority when Priority exists in the entity.
* Included Priority in Activation Rule user interface, POCOs, and migrations; ensured invocation and synchronization preserve order for evaluation sequence to support rule chaining.
* Updated completions to support Activation Rules and Activation Rule chaining.
* Improved delegate compilation to avoid reflection during invocation; delegates are now compiled during synchronization, eliminating reflection usage during invocation for real-time processing.
* Created event attributes to direct matching of Inline Scripts, including matching properties given event context (to restrict to a single Activation Rule, for example).
* Separated ExecuteAsync attributes from property attributes in the solution for better organization.
* Mapped Inline Script property and method attributes during synchronization to avoid reflection during invocation.
* Removed parallel for loops and locks in Activation Rule processing to support chaining.
* Modified reflection wrapper for Inline Scripts to eliminate reflection by compiling delegates during synchronization.
* Minor refactoring and variable renaming.
* Updated Inline Script interface to mandate bool return value in ExecuteAsync method.
* Updated rule parser to support evaluation of exists activation rule match for chaining support.
* Updated sandbox code for new Inline Script format.
* Corrected some spelling in documentation.
2026-02-12 12:51:52 +02:00

80 lines
4.0 KiB
C#

/* Copyright (C) 2022-present Jube Holdings Limited.
*
* This file is part of Jube™ software.
*
* Jube™ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* Jube™ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License along with Jube™. If not,
* see <https://www.gnu.org/licenses/>.
*/
namespace Jube.Engine.EntityAnalysisModelInvoke.Context.Extensions
{
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using EntityAnalysisModelManager.EntityAnalysisModel.Models.Models.EntityAnalysisModelInlineScript;
using ReflectionHelpers;
public static class InlineScriptsExtensions
{
public static async Task<Context> ExecuteInlineScriptsAsync(this Context context)
{
if (context.Log.IsInfoEnabled)
{
context.Log.Info(
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id}.");
}
await IterateAndProcessAsync(context);
StorePerformanceFromStopwatch(context);
return context;
}
private static void StorePerformanceFromStopwatch(Context context)
{
context.EntityAnalysisModelInstanceEntryPayload.InvokeTaskPerformance.ComputeTimes.InlineScript = (int)(context.Stopwatch.ElapsedTicks * 1000000 / Stopwatch.Frequency);
if (context.Log.IsInfoEnabled)
{
context.Log.Info(
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} inline script invocation has concluded {context.Stopwatch.ElapsedTicks * 1000000 / Stopwatch.Frequency} ns.");
}
}
private static async Task IterateAndProcessAsync(Context context)
{
foreach (var inlineScript in context.EntityAnalysisModel.Collections.EntityAnalysisModelInlineScripts.Where(s => s.EntityAnalysisModelInlineScriptEvents
.Any(e => e.EntityAnalysisModelInlineScriptEventType == EntityAnalysisModelInlineScriptEventTypeEnum.Payload)))
{
try
{
if (context.Log.IsInfoEnabled)
{
context.Log.Info(
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} is going to invoke {inlineScript.InlineScriptCode}.");
}
await ReflectInlineScriptHelper.ExecuteAsync(inlineScript, context);
if (context.Log.IsInfoEnabled)
{
context.Log.Info(
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} has invoked {inlineScript.InlineScriptCode}.");
}
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
context.Log.Error(
$"Entity Invoke: GUID {context.EntityAnalysisModelInstanceEntryPayload.EntityAnalysisModelInstanceEntryGuid} and model {context.EntityAnalysisModel.Instance.Id} has tried to invoke inline script {inlineScript.InlineScriptCode} but it has produced an error as {ex}.");
}
}
}
}
}