johni johni - 3 years ago 208
C# Question

StackExchange.Redis pipelining on for-loop?

Preface



I have a simple interface that assumes dependencies between keys.
Two of its methods are:


  1. Remove(string key)
    - that removes a single key from the cache.

  2. RemoveDependentsOf(string baseKey)
    - that removes
    baseKey
    and all dependents of
    baseKey
    .


    1. The dependents of
      baseKey
      are specified in a
      Redis set
      .

    2. So in order to remove all dependents of
      baseKey
      I have to read the
      baseKey
      's set and then loop them to delete each of them.







Question



I read StackExchange.Redis documentation so I know about their legendary pipelining suppport, and according to their documentation the following code should work very efficient.

However, I cannot seem to understand how could the library pipeline the
KeyDelete
commands as the method returns a boolean value whether the key was deleted or not.

So before executing the second
KeyDelete
command, the first one should have been sent and received its response (that's not efficient).


  • What am I missing here?

  • How should have I written the below code?






public void Remove(string key)
{
_redis.KeyDelete(key);
}

public void RemoveDependentsOf(string key)
{
Remove(key);

var setKey = GetDependencySetKey(key);
RedisValue[] dependents = _redis.SetMembers(setKey);
foreach (var dependentKey in dependents)
{
RemoveDependentsOf(dependentKey);
}

// This is the way to remove the whole set
_redis.KeyExpire(setKey, TimeSpan.Zero);
}

Answer Source

You’re using synchronous methods and, although you don’t explicitly depend on the result of the KeyDelete operation, StackExchange.Redis doesn’t know that you’re not using the result. You are therefore not getting any of the pipelining benefits offered by the library.

The documentation explicitly calls out the two ways that you can use the pipelining support; use the Async method and perform a Task.WhenAll if you want to know when it’s done or use Fire and Forget. You can explicitly tell the library that you want to do this by passing CommandFlags.FireAndForget to your commands, e.g.

_redis.KeyDelete(key, CommandFlags.FireAndForget)

Note this will cause a default result to be returned from the call rather than the actual result. Given that you are disregarding those results anyway you should be OK!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download