-
Notifications
You must be signed in to change notification settings - Fork 550
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
Backwards incompatible changes to consider #1043
Comments
Some things we encountered in the past:
|
Thanks!
I was unaware of this issue. Can you give me a code sample (preferably one that works in redis-rs tests) that shows the issue?
How would you go about choosing the correct values? |
This is the most minimal example I could build: use redis::{Connection, Script};
fn main() {
let client = redis::Client::open("redis://127.0.0.1/").unwrap();
let mut con = client.get_connection().unwrap();
println!("some arg: {}", execute_script(&mut con, Some("first"), "second"));
println!("none arg: {}", execute_script(&mut con, None, "second"));
}
fn execute_script(con: &mut Connection, first: Option<&str>, second: &str) -> String {
Script::new(RETURN_FIRST_ARG).arg(first).arg(second).invoke(con).unwrap()
}
const RETURN_FIRST_ARG: &str = r#"
return redis.status_reply(ARGV[1])
"#; It will print out:
My intuition would be to have a conservative / big value, that's likely too big for most people. I think Redis is mostly chosen for speed and latency, so network latency should usually be low. Long running scripts have a default timeout of 5s on the server side. But having the Redis block for 5s is crazy for most applications. For the connection timeout there is a precendence of 1s in the async cluster. For the request timeout maybe something in the range of 1 to 5 seconds? |
I think the problem with request timeouts specifically is that a lot of Redis commands explicitly block. I think it would make for a bad experience if users don't realize there's a default request timeout in place breaking their properly constructed commands. |
Thanks for the example! Line 1084 in cc32c77
Which doesn't make sense to me. I can see how it saves some repeating lines of code, but as the example shows, it reduces actual legibility of the code - |
https://crates.io/crates/redis-protocol is a nice crate, maybe we should benchmark it.
Since aio will be gone, aio's ConnectionLike can be changed.
We could work on them. |
Let me know if there's any changes or new features you'd like to see with |
@aembke Thanks! |
One more thing that confused me today is the At first glance combining those two commands seems convenient, but I think this might be worth a breaking change to better represent the behavior of Redis, and cause less surprises. The fn hget<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
cmd(if field.is_single_arg() { "HGET" } else { "HMGET" }).arg(key).arg(field)
} |
I don't think async std is maintained anymore https://github.com/async-rs/async-std/graphs/code-frequency we can drop it. |
I agree and think we should also simplify |
renaming ConnectionInfo into RedisConfiguration and making it general would be better, for example client side caching information, resp3, push message callback. |
how about changing aio::ConnectionLike to use async fn instead of returning RedisFuture ? Ofc we need to bump MSRV. |
If I can add another suggestion, I think there should be some separation of which commands are available in cluster connections and normal connections. Currently the ClusterConnection exposes some methods that operate only on individual nodes, like Our code looked like this, which looks fine at a glance but in practice sends the scan to a random node every time, duplicating some values and skipping some others: for node_url in redis_urls {
let client = ClusterClient::builder([node_url])
.read_from_replicas()
.build()?;
let reader_conn = client.get_async_connection().await?;
let scan_iterator = reader_conn.scan().await?; I think splitting the ConnectionLike into 3 traits would be nice to make these usage errors less likely:
|
@dcamsiteimprove that's pretty similar to what we did in GLIDE for Redis. As an interim solution, you can use the |
async connections that work with shared references - |
The purpose of this list is to raise major design decisions which we should consider for a major backwards incompatible version, such as 1.0. Everyone is welcome to comment on these, or offer more suggestions.
Connections:
ConnectionInfo
's visibility - this hampers our ability to add fields with structs that we don't want to be public. We could expose a builder, instead, or rely on redis URLs. Sample issue -TlsConnParams
is opaque: Intentional? #1006Blocking operations and aio MultiplexedConnection #1236 (comment)
Parsing and values:
from_redis_value
take the value, instead of a reference. Today we have to maintain bothfrom_redis_value
andfrom_owned_redis_value
. We should removefrom_owned_redis_value
, havefrom_redis_value
take an owned value. and reduce the duplication. If the user wants to convert by reference, they can just clone the value.redis::Value
can contain better clonable values - replaceString
withArc<String>
orArcStr
, or maybe justBytes
objects. This will reduce the cost of cloning values, and if we replaceString
andVec<u8>
withBytes
it can even allow for zero-copy parsing.Async
smol
.async-std
, we can drop that support and reduce the async implementation complexity.The text was updated successfully, but these errors were encountered: