clojurewerkz / spyglass

A Clojure Memcached client (also: Couchbase, Kestrel). Built on top of SpyMemcached, supports ASCII and binary protocols, strives to be 100% feature complete.
http://clojurememcached.info
67 stars 17 forks source link

core.cache implementation problems #10

Closed xsc closed 3 years ago

xsc commented 11 years ago

The implementation in clojurewerkz.spyglass.cache seems to have some minor problems.

michaelklishin commented 11 years ago

@xsc feel free to submit a pull request!

xsc commented 11 years ago

Well I'm not sure spyglass should even contain an implementation for core.cache since those operations seem to be designed for immutable in-memory caches (no, really!). There is no concept of state in core.cache and a lot of composability relies on that fact.

More importantly, it should be guaranteed that if I call hit or miss on a cache and then perform a lookup on the result of these functions, I should not have to fear that my key expired in-between. This cannot be made sure using a memcached- or DB-backed cache.

What I'm trying to say: core.cache seems to be designed for in-memory memoization (e.g. with core.memoize) and the only time values are really purged from the data store should be when calling miss. So that's not the kind of protocol/interface/semantics a memcached-backed cache should (or is able to) implement.

michaelklishin commented 11 years ago

All this semantics was not documented by the time our core.cache implementation landed. Even though our implementation is not perfect, it is certainly not unheard of to use core.cache as a common interface to the most basic K/V operations. So it makes sense for Spyglass to provide one.

xsc commented 11 years ago

I can see that, sure. And if one implements a cache protocol it's probably best to choose the library prefixed with core.. There really is no problem with direct usability here, only when trying to integrate spyglass with libraries using core.cache does one see that it's not really suitable. (core.memoize stores e.g. values wrapped in delays which are not serializable and thus result in exceptions thrown inside of the memcached client.)

I'll still try to create an appropriate pull request, adressing the most immediate problems. Thanks for your response!

michaelklishin commented 11 years ago

Serializability of delays sounds like a core.memoize issue to me and not something inherent to caching or core.cache's protocol. Thank you for considering to contribute!

xsc commented 11 years ago

I meant to address the reasoning behind core.memoize's concrete behaviour: it expects core.cache to store keys and values in-memory, thus seeing no problem with non-serializable values. And if someone models their library to rely on the semantics they gather from core.cache and a specific cache implementation breaks said library, on which side does the issue lie?

So, the main problem is probably the naming of core.cache since it's not really a suitable abstraction over caching in general but seems to have been built as the basis for core.memoize, as well as the fact that nowhere on the core.cache page does it really describe the semantics.

(Additionally, I don't think has?/hit/miss/lookup is the right access pattern for mutable caches without transaction semantics; atomic operations like lookup-if-cached seem better to me.)

Edit: I should probably address that over there. Sorry for ranting. ;)