@@ -15,23 +15,58 @@ namespace Simpleflow.Services
1515 public class CacheService : IFlowPipelineService
1616 {
1717 private readonly IMemoryCache _cache ;
18+ private readonly string _hashingAlgToIdentifyScriptInCacheUniquely ;
19+ private readonly TimeSpan _cacheSlidingExpiration ;
1820
1921 /// <summary>
2022 ///
2123 /// </summary>
22- public CacheService ( )
24+ /// <param name="hashingAlgToIdentifyScriptInCacheUniquely">
25+ /// Check hash algorithm names here: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hashalgorithm.create?view=net-6.0
26+ /// </param>
27+ public CacheService ( string hashingAlgToIdentifyScriptInCacheUniquely = "MD5" )
2328 {
2429 //MemoryCache
2530 _cache = new MemoryCache ( new MemoryCacheOptions ( ) { } ) ;
31+
32+ // Set hashing algorithm for unique id generation
33+ if ( string . IsNullOrWhiteSpace ( hashingAlgToIdentifyScriptInCacheUniquely ) )
34+ {
35+ throw new ArgumentNullException ( nameof ( hashingAlgToIdentifyScriptInCacheUniquely ) ) ;
36+ }
37+ _hashingAlgToIdentifyScriptInCacheUniquely = hashingAlgToIdentifyScriptInCacheUniquely ;
38+
39+
40+ // Set default expiration time
41+ _cacheSlidingExpiration = TimeSpan . FromMinutes ( 3 ) ;
2642 }
2743
44+ /// <summary>
45+ ///
46+ /// </summary>
47+ /// <param name="hashingAlgToIdentifyScriptInCacheUniquely"></param>
48+ /// <param name="cacheSlidingExpiration"></param>
49+ public CacheService ( TimeSpan cacheSlidingExpiration , string hashingAlgToIdentifyScriptInCacheUniquely = "MD5" )
50+ : this ( hashingAlgToIdentifyScriptInCacheUniquely )
51+ {
52+ _cacheSlidingExpiration = cacheSlidingExpiration ;
53+ }
54+
55+
2856 /// <inheritdoc />
2957 public void Run < TArg > ( FlowContext < TArg > context , NextPipelineService < TArg > next )
3058 {
3159 // Create unique id for script to identify in cache store
3260 var id = string . IsNullOrWhiteSpace ( context . Options ? . Id ) ?
3361 GetScriptUniqueId ( context . Script ) : context . Options . Id ;
3462
63+ // GetFlowContextOptionsId helps to identify script uniquely along with options
64+ // in order to allow or deny functions
65+ if ( context . Options != null )
66+ {
67+ id += "_" + GetFlowContextOptionsId ( context . Options ) ;
68+ }
69+
3570 context . Trace . Write ( $ "Cache-Key { id } ") ;
3671
3772 // Get compiled script from cache
@@ -57,16 +92,44 @@ public void Run<TArg>(FlowContext<TArg> context, NextPipelineService<TArg> next)
5792 }
5893
5994 /// <summary>
60- /// Gets script unique id by creating hash for the input script
95+ /// Gets script unique id by creating hash (SHA256) for the input script
6196 /// </summary>
6297 /// <param name="script"></param>
6398 /// <returns></returns>
6499 protected virtual string GetScriptUniqueId ( string script )
65100 {
66101 // Calculate id for script
67- using var sha1 = SHA1 . Create ( ) ;
102+ using var sha1 = HashAlgorithm . Create ( _hashingAlgToIdentifyScriptInCacheUniquely ) ;
68103 return System . Convert . ToBase64String ( sha1 . ComputeHash ( Encoding . UTF8 . GetBytes ( script ) ) ) ;
69104 }
105+
106+ private string GetFlowContextOptionsId ( IContextOptions options )
107+ {
108+ if ( options . AllowArgumentToMutate == false
109+ && ( options . AllowOnlyFunctions == null || options . AllowOnlyFunctions . Length == 0 )
110+ && ( options . DenyOnlyFunctions == null || options . DenyOnlyFunctions . Length == 0 )
111+ )
112+ {
113+ return string . Empty ;
114+ }
115+
116+ StringBuilder sb = new StringBuilder ( ) ;
117+ sb . Append ( string . Join ( ' ' , options . AllowArgumentToMutate ) ) ;
118+
119+ if ( options . AllowOnlyFunctions != null && options . AllowOnlyFunctions . Length > 0 )
120+ {
121+ sb . Append ( "Allow" ) ; //ensure add this to avoid collisions
122+ sb . Append ( string . Join ( ' ' , options . AllowOnlyFunctions ) ) ;
123+ }
124+
125+ if ( options . DenyOnlyFunctions != null && options . DenyOnlyFunctions . Length > 0 )
126+ {
127+ sb . Append ( "Deny" ) ; //ensure add this to avoid collisions
128+ sb . Append ( string . Join ( ' ' , options . DenyOnlyFunctions ) ) ;
129+ }
130+
131+ return GetScriptUniqueId ( sb . ToString ( ) ) ;
132+ }
70133 }
71134
72135}
0 commit comments