Comments (2)
I'm just experimenting with how to solve the same issue and this seems to work nicely
public class Rule
{
public string Id {get;set;}
public string Expression {get;set;}
}
public interface IExpressionCache
{
IGenericExpression<bool> GetExpression(Rule rule, Context context);
}
public interface IExpressionCompiler
{
IGenericExpression<bool> Compiler(string expression, Context context);
bool Execute(IGenericExpression<bool> compiled, Context context);
}
public class ExpressionCache : IExpressionCache
{
private readonly IExpressionCompiler _engine;
private readonly ICache _cache;
private static object locker = new object();
public ExpressionCache(IExpressionCompiler engine, ICache cache)
{
_engine = engine;
_cache = cache;
}
public IGenericExpression<bool> GetExpression(Rule rule, Context context)
{
var key = $"rule_{rule.Id}";
// https://en.wikipedia.org/wiki/Double-checked_locking
var compiled = _cache.Get<IGenericExpression<bool>>(key);
if (compiled == null) // 1st check
{
lock (locker) // Enter critical section
{
compiled = _cache.Get<IGenericExpression<bool>>(key);
if (compiled == null) // 2nd (double) check
{
// Create a new context and cache it
compiled = _engine.Compiler(rule.Expression, context);
_cache.Set(key, compiled);
}
}
}
return compiled;
}
}
public class ExpressionCompiler : IExpressionCompiler
{
private const string _contextVariableName = "Context";
public IGenericExpression<bool> Compiler(string expression, Context context)
{
var ec = new ExpressionContext();
ec.Variables.Add(_contextVariableName, context);
return ec.CompileGeneric<bool>(expression);
}
public bool Execute(IGenericExpression<bool> compiled, Context context)
{
compiled.Context.Variables[_contextVariableName] = context;
return compiled.Evaluate();
}
}
public interface ICache
{
T Get<T>(string key);
void Set<T>(string key, T value);
}
/// <summary>
/// Naive cache
/// TODO: configure
/// </summary>
public class Cache : ICache
{
private readonly IMemoryCache _cache;
public Cache(IMemoryCache cache)
{
_cache = cache;
}
public T Get<T>(string key)
{
return _cache.Get<T>(key);
}
public void Set<T>(string key, T value)
{
_cache.Set(key, value, TimeSpan.FromSeconds(5));
}
}
from flee.
I've also implemented a cache with a simple Dictionary. I think the application would best know how to do the caching
from flee.
Related Issues (20)
- ternary operation support? HOT 3
- OutOfMemoryException HOT 1
- Support delegation HOT 1
- version 2.0.0 bug
- Cannot add variable with null value
- Bug in TokenStringDFA
- Question: Is it possible to access the ExpressionContext inside a custom function?
- Passing parameters to variable argument function
- boolean expression with decimals
- Assigning a value to a variable in an expression
- .net 8 upgrade?
- Attempting to access TimeSpan.TotalHours gives Common Language Runtime detected an invalid program.
- How to update express with CalculationEngine
- Flee.Parsing.grammatica_1._5.alpha2.PerCederberg.Grammatica.Runtime.RE.RegExpException: 'invalid repeat count: '{1,3})?(d|f|m)?' at position 18' HOT 1
- Flee nuget package update HOT 2
- Allow evaluating void return methods HOT 2
- Typo in https://github.com/mparlak/Flee/wiki/Getting-Started
- round AwayFromZero and ToEven
- no integer divisions should be allowed by default
- Support switch owner in multiple threading environment
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flee.