-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Caching of compiled rules. #63
Comments
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));
}
} |
I've also implemented a cache with a simple Dictionary. I think the application would best know how to do the caching |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I am using Flee.Net45 library for evaluating expressions in my application.
As rule compilation is taking time, can we cache the compiled rules to bypass the rule compilation process?
Sample code :
_expressionContext.CompileDynamic("expression")
Appreciate your help.
Thanks,
Balaji.
The text was updated successfully, but these errors were encountered: