@@ -9,6 +9,11 @@ internal class RedisSentinelWorker : IDisposable
9
9
{
10
10
protected static readonly ILog Log = LogManager . GetLogger ( typeof ( RedisSentinelWorker ) ) ;
11
11
12
+ static int IdCounter = 0 ;
13
+ public int Id { get ; }
14
+
15
+ private readonly object oLock = new object ( ) ;
16
+
12
17
private readonly RedisSentinel sentinel ;
13
18
private readonly RedisClient sentinelClient ;
14
19
private RedisPubSubServer sentinePubSub ;
@@ -17,6 +22,7 @@ internal class RedisSentinelWorker : IDisposable
17
22
18
23
public RedisSentinelWorker ( RedisSentinel sentinel , RedisEndpoint sentinelEndpoint )
19
24
{
25
+ this . Id = Interlocked . Increment ( ref IdCounter ) ;
20
26
this . sentinel = sentinel ;
21
27
this . sentinelClient = new RedisClient ( sentinelEndpoint ) {
22
28
Db = 0 , //Sentinel Servers doesn't support DB, reset to 0
@@ -95,7 +101,10 @@ internal string GetMasterHost(string masterName)
95
101
96
102
private string GetMasterHostInternal ( string masterName )
97
103
{
98
- var masterInfo = sentinelClient . SentinelGetMasterAddrByName ( masterName ) ;
104
+ List < string > masterInfo ;
105
+ lock ( oLock )
106
+ masterInfo = sentinelClient . SentinelGetMasterAddrByName ( masterName ) ;
107
+
99
108
return masterInfo . Count > 0
100
109
? SanitizeMasterConfig ( masterInfo )
101
110
: null ;
@@ -114,12 +123,21 @@ private string SanitizeMasterConfig(List<string> masterInfo)
114
123
115
124
internal List < string > GetSentinelHosts ( string masterName )
116
125
{
117
- return SanitizeHostsConfig ( this . sentinelClient . SentinelSentinels ( sentinel . MasterName ) ) ;
126
+ List < Dictionary < string , string > > sentinelSentinels ;
127
+ lock ( oLock )
128
+ sentinelSentinels = this . sentinelClient . SentinelSentinels ( sentinel . MasterName ) ;
129
+
130
+ return SanitizeHostsConfig ( sentinelSentinels ) ;
118
131
}
119
132
120
133
internal List < string > GetSlaveHosts ( string masterName )
121
134
{
122
- return SanitizeHostsConfig ( this . sentinelClient . SentinelSlaves ( sentinel . MasterName ) ) ;
135
+ List < Dictionary < string , string > > sentinelSlaves ;
136
+
137
+ lock ( oLock )
138
+ sentinelSlaves = sentinelClient . SentinelSlaves ( sentinel . MasterName ) ;
139
+
140
+ return SanitizeHostsConfig ( sentinelSlaves ) ;
123
141
}
124
142
125
143
private List < string > SanitizeHostsConfig ( IEnumerable < Dictionary < string , string > > slaves )
@@ -146,27 +164,30 @@ public void BeginListeningForConfigurationChanges()
146
164
{
147
165
try
148
166
{
149
- if ( this . sentinePubSub == null )
167
+ lock ( oLock )
150
168
{
151
- var sentinelManager = new BasicRedisClientManager ( sentinel . SentinelHosts , sentinel . SentinelHosts )
169
+ if ( this . sentinePubSub == null )
152
170
{
153
- //Use BasicRedisResolver which doesn't validate non-Master Sentinel instances
154
- RedisResolver = new BasicRedisResolver ( sentinel . SentinelEndpoints , sentinel . SentinelEndpoints )
155
- } ;
156
- this . sentinePubSub = new RedisPubSubServer ( sentinelManager )
157
- {
158
- HeartbeatInterval = null ,
159
- IsSentinelSubscription = true ,
160
- ChannelsMatching = new [ ] { RedisPubSubServer . AllChannelsWildCard } ,
161
- OnMessage = SentinelMessageReceived
162
- } ;
171
+ var sentinelManager = new BasicRedisClientManager ( sentinel . SentinelHosts , sentinel . SentinelHosts )
172
+ {
173
+ //Use BasicRedisResolver which doesn't validate non-Master Sentinel instances
174
+ RedisResolver = new BasicRedisResolver ( sentinel . SentinelEndpoints , sentinel . SentinelEndpoints )
175
+ } ;
176
+ this . sentinePubSub = new RedisPubSubServer ( sentinelManager )
177
+ {
178
+ HeartbeatInterval = null ,
179
+ IsSentinelSubscription = true ,
180
+ ChannelsMatching = new [ ] { RedisPubSubServer . AllChannelsWildCard } ,
181
+ OnMessage = SentinelMessageReceived
182
+ } ;
183
+ }
163
184
}
185
+
164
186
this . sentinePubSub . Start ( ) ;
165
187
}
166
188
catch ( Exception ex )
167
189
{
168
- Log . Error ( "Error Subscribing to Redis Channel on {0}:{1}"
169
- . Fmt ( this . sentinelClient . Host , this . sentinelClient . Port ) , ex ) ;
190
+ Log . Error ( $ "Error Subscribing to Redis Channel on { this . sentinelClient . Host } :{ this . sentinelClient . Port } ", ex ) ;
170
191
171
192
if ( OnSentinelError != null )
172
193
OnSentinelError ( ex ) ;
@@ -175,7 +196,8 @@ public void BeginListeningForConfigurationChanges()
175
196
176
197
public void ForceMasterFailover ( string masterName )
177
198
{
178
- this . sentinelClient . SentinelFailover ( masterName ) ;
199
+ lock ( oLock )
200
+ this . sentinelClient . SentinelFailover ( masterName ) ;
179
201
}
180
202
181
203
public void Dispose ( )
0 commit comments