Skip to content
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

Variable-length pipeline response #366

Open
cssivision opened this issue Jul 21, 2020 · 3 comments
Open

Variable-length pipeline response #366

cssivision opened this issue Jul 21, 2020 · 3 comments

Comments

@cssivision
Copy link

cssivision commented Jul 21, 2020

Cargo.toml

redis = "0.16"

current API allow us to use pipeline

let (k1, k2) : (i32, i32) = redis::pipe()
    .cmd("zcard").arg("key_1")
    .cmd("zcard").arg("key_2").query(&con).unwrap();

but sometimes we don't know the length of a pipeline's response.

for example, we have x zcard command, we don't know the explicit value of x.

I try to write code like this:

let result: Vec<Option<isize>> = redis::pipe()
    .cmd("zcard").arg("key_1")
    .cmd("zcard").arg("key_2")
    .cmd("zcard").arg("key_3")
    .cmd("zcard").arg("key_4")
    .cmd("zcard").arg("key_5")
    .cmd("zcard").arg("key_6")
    .......
    .cmd("zcard").arg("key_x").query(&con).unwrap();

most time, it works fine, but the length of response not equal to the length of pipeline commands occasionally.

I guess that, current API don't support this usage?

any idea to fix this problem?

@weihanglo
Copy link
Contributor

FromRedisValue is implmented for Vec as following:
https://github.com/mitsuhiko/redis-rs/blob/4d8501b8a9fac6763afdafccb8dc1f80f8cbb739/src/types.rs#L909-L917

I guess some of the responses cannot deserialize to Option<isize> and then be filtered out. Could you please modify the type to Vec<redis::Value> and inspect lengths of commands and result again? 🙇🏽‍♂️

@weihanglo
Copy link
Contributor

BTW, just incidentally spotted a counter-intuitive behavior for redis::pipe (to me). Supposed sending pipeline commands via redis-cli would get array of all command responses no matter failed or not, as below:

$  echo -e 'zcard key_1\nzcard key_2\nzcard key_3' | redis-cli
(error) WRONGTYPE Operation against a key holding the wrong kind of value
(error) WRONGTYPE Operation against a key holding the wrong kind of value
(integer) 0

These behavior also matches what transaction in redis-cli does:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> ZCARD key_1
QUEUED
127.0.0.1:6379> ZCARD key_2
QUEUED
127.0.0.1:6379> ZCARD key_3
QUEUED
127.0.0.1:6379> EXEC
1) (error) WRONGTYPE Operation against a key holding the wrong kind of value
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 0

However, all of the req_packed_commands implementations return only ONE Err if there is one. Perhaps returning an Vec<RedisResult> is more appropriate when pipelining.

https://github.com/mitsuhiko/redis-rs/blob/1e12518573d00ceed85a23c6574411098e0c3fce/src/connection.rs#L793-L798

Just FYI. Not sure did you also encounter the same problem.

@nihohit
Copy link
Contributor

nihohit commented Mar 25, 2024

@cssivision is this issue still present? can you provide sample code to recreate it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants