Skip to content

Commit 1839cd6

Browse files
authored
Merge pull request #9 from navtech-io/develop
Develop
2 parents e87f7bb + 0c4dfff commit 1839cd6

File tree

14 files changed

+110
-86
lines changed

14 files changed

+110
-86
lines changed

build/Build.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ class Build : NukeBuild
125125
.AddProperty("PackageLicenseExpression", "Apache-2.0")
126126
.AddProperty("PackageIcon", @"PackageIcon.png")
127127
.SetIncludeSymbols(true)
128-
.SetVersion("0.1.0-beta06")
129128
.SetDescription("Build dynamic rules and workflows using script")
130129
.SetPackageTags("Simpleflow.NET Workflow RuleEngine DynamicExpressionEvaluator")
131130
.SetNoDependencies(true)

src/Simpleflow/CacheOptions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ public class CacheOptions
2020
public System.DateTimeOffset? AbsoluteExpiration { get; set; }
2121

2222
/// <summary>
23-
/// Gets or sets hashing algorithm to identify script compiled object uniquely
23+
/// Gets or sets hashing algorithm to identify script compiled object uniquely. This method is used when no script id specified.
2424
/// Check available hash algorithms and names here: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.create?view=net-6.0
2525
/// </summary>
2626
public string HashingAlgToIdentifyScriptUniquely { get; set; } = "MD5";
27+
2728
}
2829
}

src/Simpleflow/FlowContext.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22
// See License in the project root for license information.
33

44
using System;
5-
using System.Dynamic;
65

76
namespace Simpleflow
87
{
98
/// <summary>
10-
/// A <see cref="FlowContext"/> instance represents input, output, and which has
11-
/// special property "Items" can be used by middleware to share data among.
9+
/// A <see cref="FlowContext&lt;TArg&gt;"/> instance represents input and output.
1210
/// </summary>
1311
public sealed class FlowContext<TArg>
1412
{
@@ -36,16 +34,26 @@ public sealed class FlowContext<TArg>
3634
public FlowOutput Output { get; } = new FlowOutput();
3735

3836
/// <summary>
39-
/// Gets trace to verify the executed middleware
37+
/// Gets trace to verify the middleware info
4038
/// </summary>
41-
public SimpleflowTrace Trace { get; } = new SimpleflowTrace();
39+
public SimpleflowTrace Trace { get; private set; }
4240

41+
4342
/// <summary>
4443
///
4544
/// </summary>
4645
public FlowInternals Internals { get; } = new FlowInternals();
4746

48-
47+
/// <summary>
48+
///
49+
/// </summary>
50+
public void EnableTrace()
51+
{
52+
Trace = new SimpleflowTrace();
53+
}
54+
55+
56+
4957
/// <summary>
5058
///
5159
/// </summary>
@@ -55,11 +63,6 @@ public class FlowInternals
5563
///
5664
/// </summary>
5765
public Action<FlowInput<TArg>, FlowOutput, ScriptHelperContext> CompiledScript { get; set; }
58-
59-
/// <summary>
60-
///
61-
/// </summary>
62-
public dynamic Tag { get; } = new ExpandoObject();
6366
}
6467
}
6568
}

src/Simpleflow/FlowContextOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ public class FlowContextOptions : FlowOptions, IContextOptions
1717
/// </summary>
1818
public string Id { get; set; }
1919

20+
/// <inheritdoc/>
21+
public bool ResetCache { get; set; }
2022
}
2123
}

src/Simpleflow/FunctionRegister.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Diagnostics;
7-
using System.Net.Http.Headers;
8-
using Simpleflow.Functions;
7+
98
using Simpleflow.Exceptions;
109

1110
namespace Simpleflow
@@ -121,7 +120,7 @@ public Delegate GetFunction(string name)
121120
/// <param name="name"></param>
122121
/// <returns></returns>
123122

124-
public bool? IsFunctionAvailableInClass(string name)
123+
private bool? IsFunctionAvailableInClass(string name)
125124
{
126125
if (_bitmapIndex.ContainsKey(name))
127126
{

src/Simpleflow/IContextOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,10 @@ public interface IContextOptions : IOptions
1212
/// Gets unique id of the script
1313
/// </summary>
1414
string Id { get; }
15+
16+
/// <summary>
17+
/// Reset cache allows to remove the item from cache if exists and add it once its compiled.
18+
/// </summary>
19+
public bool ResetCache { get; set; }
1520
}
1621
}

src/Simpleflow/Services/CacheService.cs

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -47,41 +47,25 @@ public CacheService() : this(new CacheOptions())
4747
/// <inheritdoc />
4848
public void Run<TArg>(FlowContext<TArg> context, NextPipelineService<TArg> next)
4949
{
50+
// Add trace for debugging
51+
context.Trace?.CreateNewTracePoint(nameof(CacheService));
52+
5053
// Create unique id for script to identify in cache store
51-
var id = string.IsNullOrWhiteSpace(context.Options?.Id) ?
54+
var id = string.IsNullOrWhiteSpace(context.Options?.Id) ?
5255
GetScriptUniqueId(context.Options?.CacheOptions, context.Script) : context.Options.Id;
5356

54-
// GetFlowContextOptionsId helps to identify script uniquely along with options
55-
// in order to allow or deny functions
56-
if (context.Options != null)
57-
{
58-
id += "_" + GetFlowContextOptionsId(context.Options);
59-
}
60-
61-
context.Trace.Write($"Cache-Key {id}");
57+
context.Trace?.Write($"Cache-Key {id}");
6258

63-
// Get compiled script from cache
64-
var compiledScript = _cache.Get< Action<FlowInput<TArg>, FlowOutput, ScriptHelperContext>>(key: id);
65-
if (compiledScript != null)
66-
{
67-
context.Trace.Write($"Read from cache {id} - Succeeded");
68-
context.Internals.CompiledScript = compiledScript;
69-
}
59+
// Get compiled script from cache and set it to context in order to avoid recompilation
60+
var isAvailableInCache = GetAndSetToContextTheCompiledScript(context, id);
7061

7162
// Invoke next service in pipeline
7263
next?.Invoke(context);
7364

74-
// Cache compiled script
75-
if (compiledScript == null && context.Internals.CompiledScript != null)
65+
// Cache the compiled script
66+
if (!isAvailableInCache && context.Internals.CompiledScript != null)
7667
{
77-
_cache.Set(key: id,
78-
value: context.Internals.CompiledScript,
79-
options: new MemoryCacheEntryOptions {
80-
AbsoluteExpiration = context.Options?.CacheOptions?.AbsoluteExpiration ?? _cacheOptions.AbsoluteExpiration,
81-
SlidingExpiration = context.Options?.CacheOptions?.SlidingExpiration ?? _cacheOptions.SlidingExpiration
82-
});
83-
84-
context.Trace.Write($"Saved into cache {id} - Succeeded");
68+
StoreIntoCacheCompiledScript(context, id);
8569
}
8670
}
8771

@@ -98,34 +82,44 @@ protected virtual string GetScriptUniqueId(CacheOptions contextCacheOptions, str
9882
return System.Convert.ToBase64String(sha1.ComputeHash(Encoding.UTF8.GetBytes(script)));
9983
}
10084

101-
private string GetFlowContextOptionsId(IContextOptions options)
102-
{
103-
if (
104-
//options.AllowArgumentToMutate == false &&
105-
(options.AllowFunctions == null || options.AllowFunctions.Length == 0)
106-
&& (options.DenyFunctions == null || options.DenyFunctions.Length == 0)
107-
)
108-
{
109-
return string.Empty;
110-
}
11185

112-
StringBuilder sb = new StringBuilder();
113-
//sb.Append(string.Join(' ', options.AllowArgumentToMutate));
86+
private void StoreIntoCacheCompiledScript<TArg>(FlowContext<TArg> context, string id)
87+
{
88+
_cache.Set(key: id,
89+
value: context.Internals.CompiledScript,
90+
options: new MemoryCacheEntryOptions
91+
{
92+
AbsoluteExpiration = context.Options?.CacheOptions?.AbsoluteExpiration ?? _cacheOptions.AbsoluteExpiration,
93+
SlidingExpiration = context.Options?.CacheOptions?.SlidingExpiration ?? _cacheOptions.SlidingExpiration
94+
});
95+
96+
context.Trace?.Write($"Saved into cache {id} - Succeeded");
97+
}
11498

115-
if (options.AllowFunctions != null && options.AllowFunctions.Length > 0)
116-
{
117-
sb.Append("Allow"); //ensure add this to avoid collisions
118-
sb.Append(string.Join(' ', options.AllowFunctions));
119-
}
99+
private bool GetAndSetToContextTheCompiledScript<TArg>(FlowContext<TArg> context, string id)
100+
{
101+
var compiledScript = _cache.Get<Action<FlowInput<TArg>, FlowOutput, ScriptHelperContext>>(key: id);
102+
var isAvailableInCache = compiledScript != null;
120103

121-
if (options.DenyFunctions != null && options.DenyFunctions.Length > 0)
104+
if (isAvailableInCache)
122105
{
123-
sb.Append("Deny"); //ensure add this to avoid collisions
124-
sb.Append(string.Join(' ', options.DenyFunctions ));
106+
if (context.Options?.ResetCache ?? false)
107+
{
108+
_cache.Remove(key: id);
109+
isAvailableInCache = false; // in order to save it back
110+
111+
context.Trace?.Write($"Reset cache entry '{id}' - Succeeded");
112+
}
113+
else
114+
{
115+
context.Trace?.Write($"Read from cache {id} - Succeeded");
116+
context.Internals.CompiledScript = compiledScript;
117+
}
125118
}
126119

127-
return GetScriptUniqueId(options.CacheOptions, sb.ToString());
120+
return isAvailableInCache;
128121
}
122+
129123
}
130124

131125
}

src/Simpleflow/Services/CompilerService.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public CompilerService(IFunctionRegister functionRegister, IOptions options = nu
2929
/// <inheritdoc />
3030
public void Run<TArg>(FlowContext<TArg> context, NextPipelineService<TArg> next)
3131
{
32+
33+
// Add trace for debugging
34+
context.Trace?.CreateNewTracePoint(nameof(CompilerService));
35+
3236
/* Compile if CompiledScript is null,
3337
Not-null means, it might be supplied by cache service or
3438
any other predecessor in pipeline.
@@ -39,16 +43,16 @@ So here we don't need to run again */
3943
var eventPublisher = new ParserEventPublisher();
4044
CheckFunctionExecutionPermissions(context, eventPublisher);
4145

42-
context.Internals.CompiledScript =
46+
context.Internals.CompiledScript =
4347
SimpleflowCompiler.Compile<TArg>(context.Script,
4448
new FunctionRegisterCoordinator(_functionRegister, context.FunctionRegister),
4549
eventPublisher);
4650

47-
context.Trace.Write("Compiled");
51+
context.Trace?.Write("Compiled");
4852
}
4953
else
5054
{
51-
context.Trace.Write("Compilation Skipped");
55+
context.Trace?.Write("Compilation Skipped");
5256
}
5357

5458
next?.Invoke(context);

src/Simpleflow/Services/ExecutionService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ public class ExecutionService : IFlowPipelineService
1111
/// <inheritdoc />
1212
public void Run<TArg>(FlowContext<TArg> context, NextPipelineService<TArg> next)
1313
{
14+
// Add trace for debugging
15+
context.Trace?.CreateNewTracePoint(nameof(ExecutionService));
16+
17+
1418
var flowInput = new FlowInput<TArg>( context.Argument, options:null );
1519
var scriptHelperContext = new ScriptHelperContext(context.Output);
1620

src/Simpleflow/Simpleflow.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ private void RunPipelineService<TArg>(LinkedListNode<IFlowPipelineService> servi
8181
(flowInput) => RunPipelineService<TArg>(serviceNode.Next, flowInput)
8282
: default(NextPipelineService<TArg>);
8383

84-
// Add trace for debugging
85-
input.Trace.CreateNewTracePoint(serviceNode.Value.GetType().FullName);
86-
8784
serviceNode.Value.Run(input, next);
8885
}
8986
}

0 commit comments

Comments
 (0)