Conversation
|
Hello , Thanks for your PR. Do as you said, I noticed that Redis 5.0 streams support acknowledgment of tasks as they are completed by a group. It seems to be the feature we need, so we need to discuss whether to complete this work using streams now. Useful link: https://redis.io/topics/streams-intro What do you think? @xiangxiren |
|
Hi, |
|
Hello, @MahmoudSamir101 What do you think about using Redis Stream to implement publish and subscribe? |
|
@yang-xiaodong, yes As I see, streams and channels can be used interchangeably based on the use case, many cases can benefit from the pub/sub nature of channels without the need to append these messages indefinitely to the storage or even go forward /backward with messages like streams. Publishing messages to Another use case can be, using the notifications will be published through Anyway, if you have concerns about the nature of channels' work and they will not fit with the |
|
Hi @MahmoudSamir101 , Let me explain the goal of CAP CAP is a solution to deal with transaction consistency in distributed scenarios. We need to try our best to ensure the reliability of messages in most unreliable scenarios, so we adopt the outbox pattern and use local transactions on the producer side to achieve strong consistency. This allows us to first ensure that the message on the producer side will not be lost due to failure to reach the MQ or exceptions in the delivery process. On the consumer side, we need to use the Ack feature provided by the message queue to ensure that the message is stored in the inbox, so as to achieve "at least once". At the same time, we provide features similar to Kafka consumer groups to implement load balancing or broadcasting of messages on the consumer side. Prior to this, we did not implement Redis Transport because Redis did not have the features we needed and could not achieve our goals. Now when I learned about the Streams feature, I found that it provides the functionality we need and is able to do this and I investigated other EDA architectures, for example, Dapr also use Redis Streams to implement publish and subscribe. Therefore, I think Streams is more suitable for CAP. At the same time I want to invite you to join us, do you have interest to join us as a maintainer? |
|
@yang-xiaodong, I got your point, and I'm interested to have a look at implementing Redis streams with CAP. I would like to join the CAP community for contribution and maintenance for sure. |
|
Hello @MahmoudSamir101, Any updates about this PR? |
|
@yang-xiaodong , yes I'm planning to push my updates soon, may be next Thursday or before that. |
|
@yang-xiaodong could you please check the updates. Some points to be considered:
Let me know your thoughts about that. |
| using DotNetCore.CAP; | ||
| using DotNetCore.CAP.Internal; | ||
| using StackExchange.Redis; | ||
| using System; |
There was a problem hiding this comment.
According to our specifications, the System namespace needs to be placed at the first
| public static CapOptions UseRedis(this CapOptions options, Action<CapRedisOptions> configure) | ||
| { | ||
| if (configure is null) | ||
| throw new ArgumentNullException(nameof(configure)); |
There was a problem hiding this comment.
Add directly after the if line, or use {} to include on a new line
| @@ -0,0 +1,71 @@ | |||
| // Copyright (c) .NET Core Community. All rights reserved. | |||
There was a problem hiding this comment.
Is this the file to be deleted?
<ItemGroup>
<Compile Remove="IProcessingServer.PollPendingTopic.cs" />
</ItemGroup>
| using System.Threading.Tasks; | ||
| using System.Reflection; | ||
|
|
||
| namespace DotNetCore.CAP.Redis |
There was a problem hiding this comment.
Should be namespace Microsoft.Extensions.DependencyInjection
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Net; | ||
| using System.Text; | ||
| using System.Threading.Tasks; |
There was a problem hiding this comment.
Place System namespace at first
| <ItemGroup> | ||
| <Compile Remove="IProcessingServer.PollPendingTopic.cs" /> | ||
| </ItemGroup> |
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using System.Threading.Tasks; |
There was a problem hiding this comment.
Place System namespace at first
| using System.Text; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace DotNetCore.CAP.Redis |
| catch (Exception ex) | ||
| { | ||
| logger.LogError($"Redis error when trying read consumer group {consumerGroup}", ex); | ||
| return (false, Array.Empty<RedisStream>()); | ||
| } |
There was a problem hiding this comment.
According to my test, we will encounter two exception here.
- When the Redis server restart, the first exception will be encountered
SocketFailure (ReadSocketError/ConnectionReset, last-recv: 5) on 192.168.3.57:6379/Interactive, Idle/Faulted, last:
XREADGROUP
- After the redis server restarts, the consumer group will be lost, The exception information is as follows
NOGROUP No such key 'test-message' or consumer group 'Samples.Redis.SqlServer.v1' in XREADGROUP with GROUP option
There was a problem hiding this comment.
PS: If transport throw BrokerConnectionException exception, the TransportCheckProcessor will restart consumer every 30 seconds
|
Hello @MahmoudSamir101 , Thanks for your PR. During my review process, I think we need to consider several points
|
ensure consumer group creation while reading from stream
|
@yang-xiaodong @xiangxiren thanks for your review, kindly find my response inline
renamed to RedisStreams
OK, good point, now while reading a consumer group, if it does not exist or the stream was not created, we are creating both again.
Let me explain why we might not need that. Messages are not marked as ack until the CAP server invokes the client commit method while reading from a consumer group; therefore, if the storage fails, there will be no invoke for client commit to ack the message; instead, the message is marked as pending on the consumer group, and pending messages are consumed again with the next START of Cap server. I believe we should double-check this assumption. The CAP server consumed pending messages again with the next start. |
|
@yang-xiaodong Will you want me to change the docs ? |
|
@MahmoudSamir101 Yes, that will be nice |
|
@yang-xiaodong, I created a PR #862 for documentation updates |


Hello their,
this is my PR for adding redis to Cap project, the PR provides pub/sub using redis channels, and later on, we can add redis streams support.
the PR has a sample for testing, you may need docker to run redis image, as there is a post build command that will run redis image container
let me know if it helps, your observations most welcome.
Thanks.