-
Notifications
You must be signed in to change notification settings - Fork 98
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
Add Redis store type #72
Conversation
Thanks for taking this on @omid ! Sorry, I haven't had much time recently to review this. This looks like a great start. There's a couple things I'd to iron out:
Another thing to think about (probably out of scope for this PR, so just something to keep in mind for now) is connection pooling. I don't think redis-rs supports it out of the box, instead requiring you to use an r2d2 or mobc wrapper. It's a tricky problem, but what I'd like to eventually allow is for calling code to provide a pool of some sort so this library isn't doing any resource management, instead letting the caller handle it. This might mean having to understand a raw connection vs r2d2-pool vs mobc-pool, or providing a "RedisCache" trait to abstract over the three, this lib could provide impl's for the common ones but always allow callers to provide their own. |
Thanks @jaemk :)
Sure, I'll introduce two methods,
You mean to have two different features, like
Sure 👍🏼
You are right, we need this and redis-rs doesn't have it yet. And as you said, let's do it in another PR. 🤔 /// |
@jaemk ping 🙃 |
_phantom: PhantomData<K>, | ||
} | ||
|
||
const ENV_KEY: &str = "REDIS_CS"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be optionally specified as a parameter when building the RedisCache
struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, are you fine that I introduce two new methods, set_prefix
and set_connection_string
to use instead of these two constants?
let val = f().await; | ||
self.base_set(&key, &val); | ||
let index = self.store.len(); | ||
self.store.push(val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the reason for also storing the value in a vec?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To return a reference to it, since it's in the trait signature. If you know a better way, please don't hesitate.
src/stores/redis.rs
Outdated
} | ||
Err(_) => { | ||
let val = f().await; | ||
self.base_set(&key, &val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you make the set and get interaction with redis async?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a problem here.
In the redis-rs library, we have two different methods, get_connection
which is sync and get_async_connection
which is async. The second one will be available if you have the Cargo.toml async feature enabled. There is no problem here :) (ref: 1)
We have some other functions for general Redis commands, like get
, which will be sync by default, but will be async based on the trait you use
. So same method, but different behaviors. (refs: 1, 2)
Also, I think this Redis implementation should be all async.
But the problem is that there are two sets of cached
methods, Cached
and CachedAsync
traits.
I still don't know why do we have two? Why are we able to disable CachedAsync
by a feature flag and not to have it all the time (just compilation speed?)? And cannot we merge them?
If it is possible to merge them and make both sets async
, I think all my issues here will be solved.
src/stores/redis.rs
Outdated
self.clean_up(); | ||
let mut con = self.client.get_connection().unwrap(); | ||
redis_rs::cmd("EVAL") | ||
.arg("local keys = redis.call('keys', ARGV[1]) \n for i=1,#keys,5000 do \n redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) \n end \n return keys") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comments on what's going on here would be helpful. Is there a benefit of doing this over regular code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll put a comment in the code also.
But it's the way to delete an unlimited number of keys, matching with a pattern, in Redis :|
Copied from here: https://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis#comment39607023_16974060
Hey @jqnatividad |
I changed this code to support sync Redis for now, until we do support async storages, mentioned here: #98 |
Hi @jaemk , any chance this will make it to the next release? |
Still looking this over. I'll try to merge in the next couple of days and will make some additions before releasing. |
I haven't forgotten about this, it's just taking me a bit longer than I expected - incorporating some ideas mentioned in #98 so the implementation doesn't need to go through as many hoops to fit the Cached trait. My plan is still the same though, will merge this PR shortly and then apply some patches before releasing. |
Okay - released in |
Fixes #68