key.Exists为过期密钥返回true

时间:2014-07-17 15:19:12

标签: redis stackexchange.redis

可能是我错过了一般的东西,我很抱歉。 但是在我的测试中,当我检查存在的过期密钥(哈希)时,它返回true:

这里"缓存"是IDatabase实例

// This will return true
var exists = cache.KeyExists(key);
// This will return null
var ttl = cache.KeyTimeToLive(key);
// This will return null
var fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None);

此外,使用When.NotExists设置将起作用:

cache.HashSetAsync(key, "full", value, When.NotExists, CommandFlags.PreferMaster);

更新

@Marc_Gravell回答帮助我在测试中找到了问题: 当我设置过期时间太短(约500毫秒)时,我收到这种奇怪的行为。 当我把它改为1或2秒时 - 我的测试现在正在通过。

已更改 Marc的示例中,这也会发生(我将到期时间更改为400毫秒):

[Test]
    public void Exec()
    {
        var key = "testKey";
        using (var conn = CreateConnection())
        {
            var cache = conn.GetDatabase();

            // setup some data
            cache.KeyDelete(key);

// cache.HashSet(key," full"," some value"); // cache.KeyExpire(key,TimeSpan.FromSeconds(3));

            cache.HashSetAsync(key, "full", "some value", When.NotExists, CommandFlags.PreferMaster);
            cache.HashSetAsync(key, "last_accessesed", "some other data", When.NotExists, CommandFlags.PreferMaster);
            cache.KeyExpireAsync(key, DateTime.UtcNow.AddMilliseconds(400), CommandFlags.FireAndForget);



            // test while exists
            var exists = cache.KeyExists(key);
            var ttl = cache.KeyTimeToLive(key);
            var fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None);
            Assert.IsTrue(exists, "key exists");
            Assert.IsNotNull(ttl, "ttl");
            Assert.AreEqual("some value", (string)fullWait.Result);

带来

  ttl
  Expected: not null
  But was:  null

更新2:

这段代码昨天对我很好,但现在不行。

   private ConnectionMultiplexer CreateConnection()
    {
        ConnectionMultiplexer connection =ConnectionMultiplexer.Connect(
     "myserver.redis.cache.windows.net,ssl=false,password=password-here");

        return connection;
    }

        [Ignore]
        [Test]
        public void Exec()
        {
        var key = "testKey";
        using (var conn = CreateConnection())
        {
            var cache = conn.GetDatabase();

            // setup some data
            cache.KeyDelete(key);
            cache.HashSetAsync(key, "full", "some value", When.NotExists, CommandFlags.PreferMaster);
            cache.HashSetAsync(key, "last_accessesed", "some other data", When.NotExists, CommandFlags.PreferMaster);
            cache.KeyExpireAsync(key, DateTime.UtcNow.AddMilliseconds(2000), CommandFlags.FireAndForget);

            // test while exists
            var exists = cache.KeyExists(key);
            var ttl = cache.KeyTimeToLive(key);
            var fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None);
            Assert.IsTrue(exists, "not expired key exists");
            Assert.IsNotNull(ttl, "ttl");
            Assert.AreEqual("some value", (string)fullWait.Result);

            // wait for expiry
            Thread.Sleep(TimeSpan.FromMilliseconds(5000));

            // test once expired
            exists = cache.KeyExists(key);
            ttl = cache.KeyTimeToLive(key);
            fullWait = cache.HashGetAsync(key, "full", flags: CommandFlags.None);
            Assert.IsFalse(exists, "expired key exists");
            Assert.IsNull(ttl, "ttl");
            Assert.IsNull((string)fullWait.Result);
        }
    }

Assert.IsFalse(exists, "expired key exists");

返回

  expired key exists
  Expected: False
  But was:  True

更改为使用秒数没有帮助:

  cache.KeyExpireAsync(key, DateTime.UtcNow.AddSeconds(3), CommandFlags.FireAndForget);
  ...
  // wait for expiry
  Thread.Sleep(TimeSpan.FromSeconds(10));

返回相同的结果(Assert.IsFalse(存在,"过期密钥存在")

  expired key exists
  Expected: False
  But was:  True

1 个答案:

答案 0 :(得分:2)

我无法重现这一点;你说KeyExists返回trueKeyTimeToLive返回null - 这听起来像是一个没有过期的关键,然后 - 但是存在。

然后你说fullWait返回null - 如果key的哈希值没有针对名称"full"设置字段,就会发生这种情况。< / p>

预计HashSetAsync工作;有趣的问题是:等待时它会返回true还是false

这传递了,例如:

[TestFixture]
public class SO24807536 : TestBase
{
    public void Exec()
    {
        var key = Me();
        using(var conn = Create())
        {
            var cache = conn.GetDatabase();

            // setup some data
            cache.KeyDelete(key);
            cache.HashSet(key, "full", "some value");
            cache.KeyExpire(key, TimeSpan.FromSeconds(3));

            // test while exists
            var exists = cache.KeyExists(key);
            var ttl = cache.KeyTimeToLive(key);
            var fullWait = cache.HashGetAsync(key, "full",
                flags: CommandFlags.None);
            Assert.IsTrue(exists, "key exists");
            Assert.IsNotNull(ttl, "ttl");
            Assert.AreEqual("some value", (string)fullWait.Result);

            // wait for expiry
            Thread.Sleep(TimeSpan.FromSeconds(4));

            // test once expired
            exists = cache.KeyExists(key);
            ttl = cache.KeyTimeToLive(key);
            fullWait = cache.HashGetAsync(key, "full",
                flags: CommandFlags.None);                
            Assert.IsFalse(exists, "key exists");
            Assert.IsNull(ttl, "ttl");
            Assert.IsNull((string)fullWait.Result);
        }
    }
}

我很乐意调查,但到目前为止看起来它的表现正常。