NewLifeX / NewLife.Redis

High performance redis client, support NETCore/. NET4. 0/. NET4. 5. It is specially optimized for big data and message queue. The average daily consumption of online single application is 10 billion. 高性能Redis客户端,支持.NETCore/.NET4.0/.NET4.5,为大数据与消息队列而特别优化,线上单应用日均100亿调用量

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

可靠redis队列里的高级用法中消息体和消息键好像不是可靠消息

ZevFung opened this issue · comments

    /// <summary>高级消费消息。消息处理成功后,自动确认并删除消息体</summary>
    /// <remarks>
    /// Publish 必须跟 ConsumeAsync 配对使用。
    /// </remarks>
    /// <param name="func"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
   public async Task<TResult> ConsumeAsync<TResult>(Func<T, Task<TResult>> func, Int32 timeout = 0)
    {
        RetryAck();

        // 取出消息键
        var msgId = timeout < 0 ?
            await ExecuteAsync((rc, k) => rc.ExecuteAsync<String>("RPOPLPUSH", Key, AckKey), true) :
            await ExecuteAsync((rc, k) => rc.ExecuteAsync<String>("BRPOPLPUSH", Key, AckKey, timeout), true);
        if (msgId.IsNullOrEmpty()) return default;

        _Status.Consumes++;
        // 取出消息。如果重复消费,或者业务层已经删除消息,此时将拿不到
        if (!Redis.TryGetValue(msgId, out T messge))
        {
            // 拿不到消息体,直接确认消息键
            Acknowledge(msgId);
            return default;
        }
       // 处理消息。如果消息已被删除,此时调用func将受到空引用
        var rs = await func(messge);

        // 确认并删除消息
        Redis.Remove(msgId);
        Acknowledge(msgId);

        return rs;
    }

func执行是否成功,都会调用Redis.Remove(msgId);和Acknowledge(msgId);,消息都会自动删除和确认。这里我觉得func不成功,就不调用Redis.Remove(msgId);和Acknowledge(msgId);

commented

func是否执行成功,是以抛出异常为准。只要没有抛出异常,就认为执行成功,需要确认消息

谢谢