Skip to content
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

关于表达式缓存的使用优化(避免一些Surprise的感觉) #330

Closed
oldratlee opened this issue Dec 15, 2020 · 2 comments
Closed

Comments

@oldratlee
Copy link
Contributor

oldratlee commented Dec 15, 2020

下面的使用方式有 Surprise的感觉:

  • 调用了AviatorEvaluatorInstanceuseLRUExpressionCacheuse*ExpressionCache)方法,
    但不会生效表达式缓存,有些surprise。
  • 还需要在执行(类execute方法)时,传递上cached参数为true,才生效表达式缓存。
    • 在执行时,设置『表达式是否缓存』,更显意,是好的。 :")
    • 在执行时,感觉可能有些繁琐; 因为执行方法可能会在不同地方多次执行。
    • 如果『表达式是否缓存』能在AviatorEvaluatorInstance上有个缺省设置:
      • 可以避免上面的『感觉繁琐』
      • 执行时的『表达式是否缓存』设置,可以显意覆盖AviatorEvaluatorInstance级的设置。
  • 详见下面的show case代码。

上面可能问题的解决方法(API设计)是不是 可以下面的做法:

  1. AviatorEvaluatorInstance级,可以(缺省)设置『表达式是否缓存』
  2. useLRUExpressionCache/use*ExpressionCache 方法,隐含了AviatorEvaluatorInstance级『表达式要缓存』
    • 顾名思意,符合方法命名(use*ExpressionCache)的直觉,没有Surprise。
    • 这里要注意,向后兼容 的问题。
  3. 考虑AviatorEvaluatorInstance级默认开启『表达式要缓存』? @killme2008
    • 对于大流量线上产品,动态编译出来的Class回收慢会压跨应用。
    • 但默认开启如何设置缓存大小是个难题?😂
    • 向后兼容 的问题

如果上面的思路/解决方法觉得OK,我可以试着给个PR。:")


public class ExpressionCacheBehaviorSurpriseTest {
    @Test
    public void call_useLRUExpressionCache_butExpressionNotCached__SURPRISE() {
        final Map<String, Object> context = new HashMap<>();
        context.put("var1", 10);
        context.put("var2", 20);
        final String expr = "var1 < 100 && var2 < 200";

        // --> Have called *use*LRUExpressionCache
        final AviatorEvaluatorInstance instance =
                AviatorEvaluator.newInstance().useLRUExpressionCache(100);
        final Boolean result = (Boolean) instance.execute(expr, context);
        assertTrue(result);
        // --> But expression Not cached. SURPRISE!
        assertFalse(instance.isExpressionCached(expr));
    }

    @Test
    public void shouldCall_useLRUExpressionCache_and_passCachedParameterToExecute_then_ExpressionWillCache() {
        final Map<String, Object> context = new HashMap<>();
        context.put("var1", 10);
        context.put("var2", 20);
        final String expr = "var1 < 100 && var2 < 200";

        // --> Have called *use*LRUExpressionCache
        final AviatorEvaluatorInstance instance =
                AviatorEvaluator.newInstance().useLRUExpressionCache(100);
        // --> And pass cached parameter to execute method
        final Boolean result = (Boolean) instance.execute(expr, context, true);
        assertTrue(result);
        // --> Then expression will cache
        assertTrue(instance.isExpressionCached(expr));
    }
}

PS: show case source file

相关资料

@killme2008
Copy link
Owner

最终决定引入一个属性,类似 AviatorEvaluatorInstance#setExpressionCaching(boolean) 来设置是否开启全局缓存。

@killme2008
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants