11using System . Collections . Concurrent ;
2+ using System . Xml . Linq ;
3+
24using Cysharp . Runtime . Multicast . Remoting ;
35
46using MessagePack ;
57using MessagePack . Formatters ;
68using MessagePack . Resolvers ;
79
810using Microsoft . Extensions . Options ;
11+
912using StackExchange . Redis ;
1013
1114namespace Cysharp . Runtime . Multicast . Distributed . Redis ;
1215
16+ /// <summary>
17+ /// Provides functionality for managing multicast groups using Redis as the underlying communication mechanism.
18+ /// </summary>
19+ /// <remarks>This class allows the creation and management of asynchronous and synchronous multicast groups, where
20+ /// messages can be sent to multiple receivers. It uses Redis channels for communication and supports custom
21+ /// serialization and deserialization of keys and messages.</remarks>
1322public class RedisGroupProvider : IMulticastGroupProvider , IDisposable
1423{
1524 private readonly ConcurrentDictionary < ( string Name , Type KeyType , Type ReceiverType ) , object > _groups = new ( ) ;
@@ -19,11 +28,32 @@ public class RedisGroupProvider : IMulticastGroupProvider, IDisposable
1928 private readonly ISubscriber _subscriber ;
2029 private readonly string ? _prefix ;
2130 private readonly MessagePackSerializerOptions _messagePackSerializerOptionsForKey ;
31+ private readonly Func < string , RedisChannel > _channelFactory ;
2232
33+ /// <summary>
34+ /// Initializes a new instance of the <see cref="RedisGroupProvider"/> class with the specified proxy factory,
35+ /// serializer, and configuration options.
36+ /// </summary>
37+ /// <param name="proxyFactory">The factory used to create remote proxies for interacting with Redis.</param>
38+ /// <param name="serializer">The serializer used to serialize and deserialize data for Redis operations.</param>
39+ /// <param name="options">The configuration options for the Redis group provider.</param>
2340 public RedisGroupProvider ( IRemoteProxyFactory proxyFactory , IRemoteSerializer serializer , IOptions < RedisGroupOptions > options )
2441 : this ( proxyFactory , serializer , options . Value )
2542 { }
2643
44+ /// <summary>
45+ /// Initializes a new instance of the <see cref="RedisGroupProvider"/> class, which provides functionality for
46+ /// managing Redis-based group communication using a specified remote proxy factory, serializer, and configuration
47+ /// options.
48+ /// </summary>
49+ /// <remarks>If the <see cref="RedisGroupOptions.ConnectionMultiplexer"/> property in <paramref
50+ /// name="options"/> is <see langword="null"/>, a new connection multiplexer is created using the connection string
51+ /// specified in <see cref="RedisGroupOptions.ConnectionString"/>. Otherwise, the provided connection multiplexer is
52+ /// used.</remarks>
53+ /// <param name="proxyFactory">The factory used to create remote proxies for communication. This parameter cannot be <see langword="null"/>.</param>
54+ /// <param name="serializer">The serializer used to serialize and deserialize messages. This parameter cannot be <see langword="null"/>.</param>
55+ /// <param name="options">The configuration options for the Redis group provider, including connection settings, channel factory, and
56+ /// serialization options. This parameter cannot be <see langword="null"/>.</param>
2757 public RedisGroupProvider ( IRemoteProxyFactory proxyFactory , IRemoteSerializer serializer , RedisGroupOptions options )
2858 {
2959 _proxyFactory = proxyFactory ;
@@ -39,52 +69,33 @@ public RedisGroupProvider(IRemoteProxyFactory proxyFactory, IRemoteSerializer se
3969 _subscriber = options . ConnectionMultiplexer . GetSubscriber ( ) ;
4070 }
4171 _prefix = options . Prefix ;
72+ _channelFactory = options . ChannelFactory ;
4273
4374 var messagePackSerializerOptions = ( options . MessagePackSerializerOptionsForKey ?? MessagePackSerializer . DefaultOptions ) ;
4475 _messagePackSerializerOptionsForKey = messagePackSerializerOptions . WithResolver (
4576 CompositeResolver . Create ( [ NativeGuidFormatter . Instance ] , [ messagePackSerializerOptions . Resolver ] )
4677 ) ;
4778 }
4879
80+ /// <inheritdoc />
4981 public IMulticastAsyncGroup < TKey , TReceiver > GetOrAddGroup < TKey , TReceiver > ( string name )
5082 where TKey : IEquatable < TKey >
51- => ( IMulticastAsyncGroup < TKey , TReceiver > ) _groups . GetOrAdd ( ( name , typeof ( TKey ) , typeof ( TReceiver ) ) , _ => new RedisGroup < TKey , TReceiver > ( _prefix + name , _subscriber , _proxyFactory , _serializer , _messagePackSerializerOptionsForKey , Remove ) ) ;
83+ => ( IMulticastAsyncGroup < TKey , TReceiver > ) _groups . GetOrAdd ( ( name , typeof ( TKey ) , typeof ( TReceiver ) ) , _ => new RedisGroup < TKey , TReceiver > ( _prefix + name , _channelFactory , _subscriber , _proxyFactory , _serializer , _messagePackSerializerOptionsForKey , Remove ) ) ;
5284
85+ /// <inheritdoc />
5386 public IMulticastSyncGroup < TKey , TReceiver > GetOrAddSynchronousGroup < TKey , TReceiver > ( string name )
5487 where TKey : IEquatable < TKey >
55- => ( IMulticastSyncGroup < TKey , TReceiver > ) _groups . GetOrAdd ( ( name , typeof ( TKey ) , typeof ( TReceiver ) ) , _ => new RedisGroup < TKey , TReceiver > ( _prefix + name , _subscriber , _proxyFactory , _serializer , _messagePackSerializerOptionsForKey , Remove ) ) ;
88+ => ( IMulticastSyncGroup < TKey , TReceiver > ) _groups . GetOrAdd ( ( name , typeof ( TKey ) , typeof ( TReceiver ) ) , _ => new RedisGroup < TKey , TReceiver > ( _prefix + name , _channelFactory , _subscriber , _proxyFactory , _serializer , _messagePackSerializerOptionsForKey , Remove ) ) ;
5689
5790 private void Remove < TKey , TReceiver > ( RedisGroup < TKey , TReceiver > group )
5891 where TKey : IEquatable < TKey >
5992 {
6093 _groups . TryRemove ( ( group . Name , typeof ( TKey ) , typeof ( TReceiver ) ) , out _ ) ;
6194 }
6295
96+ /// <inheritdoc />
6397 public void Dispose ( )
6498 {
6599 _createdConnectionMultiplexer ? . Dispose ( ) ;
66100 }
67101}
68-
69- public class RedisGroupOptions
70- {
71- /// <summary>
72- /// Gets or sets the connection string to connect to Redis. If <see cref="ConnectionMultiplexer"/> property is not set, this will be used.
73- /// </summary>
74- public string ConnectionString { get ; set ; } = "localhost:6379" ;
75-
76- /// <summary>
77- /// Gets or sets a ConnectionMultiplexer instance to connect to Redis. If this is set, <see cref="ConnectionString"/> property will be ignored.
78- /// </summary>
79- public ConnectionMultiplexer ? ConnectionMultiplexer { get ; set ; }
80-
81- /// <summary>
82- /// Gets or sets a prefix for the Redis key.
83- /// </summary>
84- public string ? Prefix { get ; set ; }
85-
86- /// <summary>
87- /// Gets or sets a MessagePackSerializerOptions used for serializing the key.
88- /// </summary>
89- public MessagePackSerializerOptions ? MessagePackSerializerOptionsForKey { get ; set ; }
90- }
0 commit comments