缓存API的独特之处在于,由于它们是不可变缓存,因此任何通常会在可变缓存中更改某些元数据(TTL、使用数据等)的操作都必须返回新的缓存实例。
除了实际的缓存API之外,还构建了一个“映射类似”API,以便您可以对它们使用Clojure的获取、关联、拆除操作,但这个层很难处理一些奇特的边缘情况,例如在检查项是否在缓存中以及随后查找它(发现它已“消失”)之间的竞态条件 – 尽管缓存本身是不可变的。这给上游消费者带来了问题,例如core.memoize,它必须包含自旋/重试逻辑才能避免错误地返回nil。
这就是为什么我添加了包装命名空间,它提供了更直观的“可变缓存”(通过在原子中包装不可变缓存),但这些缓存的“安全”API并不真的是“映射类似”:查找-如果不存在是最安全的函数,它提供了一种避免竞态条件和重复执行的方法,同时仍然可以在需要时按需进行查找以重新计算所需值。
创建后能够用新的哈希表值“初始化”缓存是一种内在的突变操作,同样“驱逐”也是。提供“映射类似”的获取操作是一种便利,但你必须接受如果请求的缓存条目已过期,则 خواهد nhận được nil(或“丢失”值)。
如readme注释所述:“core.cache API难以正确使用。”并且它链接到了这个
https://dev.to/dpsutton/exploring-the-core-cache-api-57al,其中讨论了将缓存当作“仅仅是映射”处理所引起的野外错误。