My first open source library, I'd like to get feed...
# server
d
My first open source library, I'd like to get feedback, thanks! It's being used internally in Production. The idea of it is not just a wrapper, but rather something like Micronaut's caching component, but that could work with other frameworks like Ktor... it allows caching and retrieving results of computations in its lambda. It has a few configuration options for expiry of those caches and generates keys based on passed parameters (strategy for naming keys can be changed). The backend storage doesnt have to be lettuce or redis, and can be implemented easily. I wouldn't mind if anybody has any idea on how to implement this better or in a more type safe way... https://github.com/dave08/kacheable
a
Nice library. I didn’t like only the
KacheableImpl
as name. It is not very kotlinsh it reminds me Java. Lettuce library has also coroutines extensions. You can use
conn.coroutines()
instead of
conn.async()
Check https://lettuce.io/core/release/reference/#_coroutines_api_based_on_reactive_operations
👍 1
d
Thanks! I didn't know they support coroutines... as for the name, naming is Hard 🤕 ... the interface already has the name Kacheable, which is used to wire up in classes using it and swap in NoOp when needed like in tests... so what name could I use for instanciation?
a
most are prefixing the interface with the word default
DefaultKacheable
👍 1
d
Re interface naming: What's the point of having a separate interface in the first place? Do you expect other implementations? This doesn't seem likely given that the KacheableImpl is the main selling point of this library (AFAIK).
d
There's the NoOp implementation for tests...
DefaultKacheable is an idea, but I dont think there'll be any other implementation apart from the NoOp one...
So its not really default...
d
Well, there's always the possibility of using mocks in tests. Some people don't like it but mocks can be seen just as a hacky way of implementing an interface 🙂
d
I've been staying away from mocks for a while now, when I go back to old test code using mocks it now gives me the shivers 😬... I guess in the meantime I'll go for DefaultKacheable, and I'll maybe consider using some kind of factory method to hide it...
d
Sorry for digressing but this topic always fascinates me. It seems that, generally, there's a trade-off between the purity of one's code/library and the convenience of its usage. In your case, you want to avoid mocks in tests and for that reason you are willing to either a) sacrifice a little bit of convenience for the users (strange naming), or b) complicate the design with a factory wrapper. To be clear, I'm not judging at all 🙂 It's just interesting how every person puts different weights to different aspects of the design problem.
d
Truth is, in some cases, I'd like to be able to "disable" caching apart from in unit tests... like when doing integration tests on our cluster... so I use a library like #hoplite to allow configuration layering and just have to set an Environment variable on my k8s deployment to "disable" my cache by using the NoOp implementation. But even without that need, I feel the complexity and maintenance cost of test code using mocks is MUCH higher when doing refactoring, adding features and upgrading dependencies... In this particular case, it's a pretty small library, but if I have a way to "stick to my principles", I try to even so...
In the beginning mocks seem to simplify making tests, but later on in the project... 🤒...
I just put out v0.1.0 with top-level functions for instantiation, used
conn.coroutines()
for Lettuce and a bit more documentation on switching the cache key naming. Thanks for the comments 😉!
@Anastasios Georgousakis Does the Lettuce coroutines implementation somehow support ScanIterator? I need to delete keys using a pattern, and I don't think the regular del function handles that...
For now I just used the sync() api with withContext(Dispatchers.IO)...
a
try to use
Copy code
conn.coroutines().keys(pattern)
It returns a flow of keys that matches the pattern.
d
If that's
KEYS
it's a blocking operation and isn't recommended in production...
From the Redis docs:
Warning: consider
KEYS
as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use
KEYS
in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using
SCAN
or sets.