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

When need use await for batch.KeyExpireAsync(key, TimeSpan.FromSeconds(expiry)) and when not? #2718

Closed
maomaomqiu opened this issue May 20, 2024 · 4 comments

Comments

@maomaomqiu
Copy link

Hi,

I use below to batch expire keys without TTL

IBatch batch = db.CreateBatch(); // IDatabase db

foreach (var key in list)
{
    batch.KeyExpireAsync(key, time);
}

batch.Execute();

It works well, but I take a look a KeyExpireAsync, in some code path it is sync, in some code path it is async.
Also some code example use await batch.KeyExpireAsync(key, time)

I try to use await batch.KeyExpireAsync(key, time); in my scenario, unluckily the later logic will never be hit

@slorello89
Copy link
Collaborator

slorello89 commented May 20, 2024

All a batch does is guarantee that all the commands within it are be sent over in one contiguous block to Redis without being mixed in with anything else from the client. I emphasize client here because it does not guarantee that Redis will not interleave other commands it receives from other clients in with the batch (to guarantee that you must use a transaction - though that has it's own set of nuances)

For your case here, I would hazard a guess that you do not need a batch, and that you'd just be better off pipelining these commands implicitly:

// execute KeyExpireAsync against all your keys, then await them all
await Task.WhenAll(list.Select(k => db.KeyExpireAsync(k, time)));

This is a very simplified example - there are caveats, e.g. if you are operating on thousands of keys you might want to paginate over them or do some command queuing to prevent timeouts, but generally you can just collect the tasks from dispatched async commands and await them all to allow the multiplexer to automagically pipeline them for you.

@maomaomqiu
Copy link
Author

Thanks @slorello89 promptly reply for this question,
All a batch does is guarantee that all the commands within it are be sent over in one contiguous block to Redis without being mixed in with anything else from the client.

I am curious for that, so how it guarantees? Could you explain it more detail further? Greatly thanks!

@slorello89
Copy link
Collaborator

@maomaomqiu, this library uses a multiplexer to send all commands, from any thread in the runtime, to Redis over a single socket (per Redis Server), when you use a batch, the commands are internally queued, and not executed until after you call Execute when you call execute, the library will prevent any other command from being sent to Redis over that connection until all of the commands from the batch have been executed.

@maomaomqiu
Copy link
Author

Thanks @slorello89, I will take a look at source code to know it more detailly! Very appreciate to your answer : )

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

2 participants