反馈关于查询获取ACL权限且设置了缓存而自己清除缓存时失败

在 Android 的 SDK,cn.leancloud:storage-android 中存在一个BUG如下

BUG原因:
如果使用AVQuery查询,且写 query.includeACL(true); 增加获取对象的 ACL 值
如果,我们设置了缓存
如果,我们设置了缓存
如果,我们设置了缓存
那么,执行清除该缓存,query.clearCachedResult(),永远是无效的
因为,得到的 String cacheKey = QueryResultCache.generateKeyForQueryCondition(getClassName(), query),cacheKey 和 请求时缓存的cacheKey 不一致,永远无法自己清除缓存。

解决BUG。
包 cn.leancloud.AVQuery;里
protected Observable> findInBackground(int explicitLimit) {
Map query = assembleParameters();
if (this.includeACL && null != query) {
query.put("returnACL", "true");
}
.......
}

把这里的

if (this.includeACL && null != query) {
query.put("returnACL", "true");
}

迁移至assembleParameters方法里。

修改后如下
public Map assembleParameters() {
conditions.assembleParameters();
Map query = conditions.getParameters();

if (this.includeACL && null != query) {
query.put("returnACL", "true");
}

return query;
}

这样,缓存的cacheKey和我们自己清理缓存的cacheKey是一直的,才能自己清除缓存。

好的,我已经PR,https://github.com/leancloud/java-unified-sdk/pull/143

目前作为LeanCloud用户的我们,可以临时这样主动清理缓存。

public static void clearCachedResult(AVQuery getQuery) {
Map query = getQuery.assembleParameters();
if (getQuery.isIncludeACL()) {
query.put("returnACL", "true");
}
String cacheKey = QueryResultCache.generateKeyForQueryCondition(getQuery.getClassName(), query);
QueryResultCache.getInstance().clearCachedFile(cacheKey);
}

感谢指出这个问题,我看了你提交的 PR,里面还是漏掉了 limit 参数,所以对 getFirstInBackground 这种请求来说,还是会出现缓存文件不一致的情况。
你们自己清理缓存的出发点是什么?另外就是如果自己清理缓存,为什么不完全遵照 SDK 内部生成缓存文件的机制呢?

感谢CTO-Jfeng的回复,我是一名大一学生,所以刚才的PR里改动不全面,本想已最简单的方式改动的,但是还是考虑补全。我已Close刚才的PR,希望LeanCloud能及时修复问题,发布新SDK。

感谢你的反馈,我这里详细说明一下那个 PR 不能合并的理由吧。
AVQuery 里面本来是希望由 QueryConditions 这个对象来负责所有查询条件的处理的,但是 AVQuery 的公开查询方法有很多种,包括:

  1. countInBackground()
  2. findInBackground()
  3. getFirstInBackground()

这几个方法还可以交叉重复调用,有些查询参数只是单次有效,并不能长久存入 QueryConditions 中,因此我们才分成两步来拼接最终的 query clause,这种方式确实不太好,也导致了你说的问题,还让 fix PR 容易产生遗漏,我们之后会考虑一下用更好的方式来实现(还是应该在公开接口 AVQuery#clearCachedResult 中完成,开发者不应该知道 cache 保存的细节)。

对于清理 query cache 这件事,我想了解一下更多的上下文,就是你们为什么需要自己来清理单个缓存文件,实际的业务场景是什么样子的。因为从设计上来说,我们希望大家更多的通过查询时的 CachePolicy 来控制查询方向,如果不希望使用本地缓存,只需要在查询时指定 AVQuery#setPolicy(CachePolicy.IGNORE_CACHE) or AVQuery#setPolicy(CachePolicy.NETWORK_ONLY) 即可,不用去关注具体的缓存文件在哪里是什么样子的。

你好,我们昨天发布了 6.5.14 版本,修复了缓存清理不对的 bug。
现在你只需要调用 AVQuery#clearCachedResult 就可以清理掉缓存文件,不需要自己去删除缓存文件了。

感谢 CTO-Jfeng 发布新版本的告知。坚信LeanCloud越做越好。