Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 59d9e7b

Browse files
committed
Dry PooledRedisClientManager
1 parent 6e62f0a commit 59d9e7b

3 files changed

Lines changed: 104 additions & 170 deletions

File tree

src/ServiceStack.Redis/PooledRedisClientManager.Disposable.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/ServiceStack.Redis/PooledRedisClientManager.ICacheClient.cs

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/ServiceStack.Redis/PooledRedisClientManager.cs

Lines changed: 104 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using System;
1414
using System.Collections.Generic;
1515
using System.Threading;
16+
using ServiceStack.Caching;
1617
using ServiceStack.Logging;
1718

1819
namespace ServiceStack.Redis
@@ -23,12 +24,12 @@ namespace ServiceStack.Redis
2324
/// 1 master and multiple replicated read slaves.
2425
/// </summary>
2526
public partial class PooledRedisClientManager
26-
: IRedisClientsManager, IRedisFailover
27+
: IRedisClientsManager, IRedisFailover, IHandleClientDispose
2728
{
2829
private static readonly ILog Log = LogManager.GetLogger(typeof(PooledRedisClientManager));
2930

3031
private const string PoolTimeoutError =
31-
"Redis Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use.";
32+
"Redis Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use.";
3233

3334
protected readonly int PoolSizeMultiplier = 10;
3435
public int RecheckPoolAfterMs = 100;
@@ -218,31 +219,7 @@ public IRedisClient GetClient()
218219
WritePoolIndex++;
219220
inActiveClient.Active = true;
220221

221-
if (this.ConnectTimeout != null)
222-
{
223-
inActiveClient.ConnectTimeout = this.ConnectTimeout.Value;
224-
}
225-
226-
if (this.SocketSendTimeout.HasValue)
227-
{
228-
inActiveClient.SendTimeout = this.SocketSendTimeout.Value;
229-
}
230-
if (this.SocketReceiveTimeout.HasValue)
231-
{
232-
inActiveClient.ReceiveTimeout = this.SocketReceiveTimeout.Value;
233-
}
234-
if (this.IdleTimeOutSecs.HasValue)
235-
{
236-
inActiveClient.IdleTimeOutSecs = this.IdleTimeOutSecs.Value;
237-
}
238-
239-
inActiveClient.NamespacePrefix = NamespacePrefix;
240-
241-
//Reset database to default if changed
242-
if (inActiveClient.Db != Db)
243-
{
244-
inActiveClient.ChangeDb(Db);
245-
}
222+
InitClient(inActiveClient);
246223

247224
return inActiveClient;
248225
}
@@ -260,7 +237,7 @@ private RedisClient GetInActiveWriteClient()
260237
for (int x = 0; x < ReadWriteHosts.Count; x++)
261238
{
262239
var nextHostIndex = (desiredIndex + x) % ReadWriteHosts.Count;
263-
var nextHost = ReadWriteHosts[nextHostIndex];
240+
RedisEndpoint nextHost = ReadWriteHosts[nextHostIndex];
264241
for (var i = nextHostIndex; i < writeClients.Length; i += ReadWriteHosts.Count)
265242
{
266243
if (writeClients[i] != null && !writeClients[i].Active && !writeClients[i].HadExceptions)
@@ -269,16 +246,8 @@ private RedisClient GetInActiveWriteClient()
269246
{
270247
if (writeClients[i] != null)
271248
writeClients[i].DisposeConnection();
272-
var client = RedisClientFactory.CreateRedisClient(nextHost.Host, nextHost.Port);
273-
274-
if (nextHost.RequiresAuth)
275-
client.Password = nextHost.Password;
276-
277-
client.Id = RedisClientCounter++;
278-
client.ClientManager = this;
279-
client.NamespacePrefix = NamespacePrefix;
280-
client.ConnectionFilter = ConnectionFilter;
281249

250+
var client = InitNewClient(nextHost);
282251
writeClients[i] = client;
283252

284253
return client;
@@ -288,6 +257,34 @@ private RedisClient GetInActiveWriteClient()
288257
return null;
289258
}
290259

260+
private RedisClient InitNewClient(RedisEndpoint nextHost)
261+
{
262+
var client = RedisClientFactory.CreateRedisClient(nextHost);
263+
client.Id = Interlocked.Increment(ref RedisClientCounter);
264+
client.ClientManager = this;
265+
client.ConnectionFilter = ConnectionFilter;
266+
if (NamespacePrefix != null)
267+
client.NamespacePrefix = NamespacePrefix;
268+
269+
return client;
270+
}
271+
272+
private void InitClient(RedisClient client)
273+
{
274+
if (this.ConnectTimeout != null)
275+
client.ConnectTimeout = this.ConnectTimeout.Value;
276+
if (this.SocketSendTimeout.HasValue)
277+
client.SendTimeout = this.SocketSendTimeout.Value;
278+
if (this.SocketReceiveTimeout.HasValue)
279+
client.ReceiveTimeout = this.SocketReceiveTimeout.Value;
280+
if (this.IdleTimeOutSecs.HasValue)
281+
client.IdleTimeOutSecs = this.IdleTimeOutSecs.Value;
282+
if (this.NamespacePrefix != null)
283+
client.NamespacePrefix = NamespacePrefix;
284+
if (client.Db != Db) //Reset database to default if changed
285+
client.ChangeDb(Db);
286+
}
287+
291288
/// <summary>
292289
/// Returns a ReadOnly client using the hosts defined in ReadOnlyHosts.
293290
/// </summary>
@@ -314,31 +311,7 @@ public virtual IRedisClient GetReadOnlyClient()
314311
ReadPoolIndex++;
315312
inActiveClient.Active = true;
316313

317-
if (this.ConnectTimeout != null)
318-
{
319-
inActiveClient.ConnectTimeout = this.ConnectTimeout.Value;
320-
}
321-
322-
if (this.SocketSendTimeout.HasValue)
323-
{
324-
inActiveClient.SendTimeout = this.SocketSendTimeout.Value;
325-
}
326-
if (this.SocketReceiveTimeout.HasValue)
327-
{
328-
inActiveClient.ReceiveTimeout = this.SocketReceiveTimeout.Value;
329-
}
330-
if (this.IdleTimeOutSecs.HasValue)
331-
{
332-
inActiveClient.IdleTimeOutSecs = this.IdleTimeOutSecs.Value;
333-
}
334-
335-
inActiveClient.NamespacePrefix = NamespacePrefix;
336-
337-
//Reset database to default if changed
338-
if (inActiveClient.Db != Db)
339-
{
340-
inActiveClient.ChangeDb(Db);
341-
}
314+
InitClient(inActiveClient);
342315

343316
return inActiveClient;
344317
}
@@ -365,14 +338,8 @@ private RedisClient GetInActiveReadClient()
365338
{
366339
if (readClients[i] != null)
367340
readClients[i].DisposeConnection();
368-
var client = RedisClientFactory.CreateRedisClient(nextHost.Host, nextHost.Port);
369-
370-
if (nextHost.RequiresAuth)
371-
client.Password = nextHost.Password;
372-
373-
client.ClientManager = this;
374-
client.ConnectionFilter = ConnectionFilter;
375341

342+
var client = InitNewClient(nextHost);
376343
readClients[i] = client;
377344

378345
return client;
@@ -500,19 +467,19 @@ public Dictionary<string, string> GetStats()
500467
}
501468

502469
var ret = new Dictionary<string, string>
503-
{
504-
{"writeClientsPoolSize", "" + writeClientsPoolSize},
505-
{"writeClientsCreated", "" + writeClientsCreated},
506-
{"writeClientsWithExceptions", "" + writeClientsWithExceptions},
507-
{"writeClientsInUse", "" + writeClientsInUse},
508-
{"writeClientsConnected", "" + writeClientsConnected},
509-
510-
{"readClientsPoolSize", "" + readClientsPoolSize},
511-
{"readClientsCreated", "" + readClientsCreated},
512-
{"readClientsWithExceptions", "" + readClientsWithExceptions},
513-
{"readClientsInUse", "" + readClientsInUse},
514-
{"readClientsConnected", "" + readClientsConnected},
515-
};
470+
{
471+
{"writeClientsPoolSize", "" + writeClientsPoolSize},
472+
{"writeClientsCreated", "" + writeClientsCreated},
473+
{"writeClientsWithExceptions", "" + writeClientsWithExceptions},
474+
{"writeClientsInUse", "" + writeClientsInUse},
475+
{"writeClientsConnected", "" + writeClientsConnected},
476+
477+
{"readClientsPoolSize", "" + readClientsPoolSize},
478+
{"readClientsCreated", "" + readClientsCreated},
479+
{"readClientsWithExceptions", "" + readClientsWithExceptions},
480+
{"readClientsInUse", "" + readClientsInUse},
481+
{"readClientsConnected", "" + readClientsConnected},
482+
};
516483

517484
return ret;
518485
}
@@ -613,5 +580,60 @@ protected void Dispose(RedisClient redisClient)
613580
redisClient.Host, redisClient.Port), ex);
614581
}
615582
}
583+
584+
public ICacheClient GetCacheClient()
585+
{
586+
return new RedisClientManagerCacheClient(this);
587+
}
588+
589+
public ICacheClient GetReadOnlyCacheClient()
590+
{
591+
return new RedisClientManagerCacheClient(this) { ReadOnly = true };
592+
}
616593
}
594+
595+
public partial class PooledRedisClientManager : IRedisClientCacheManager
596+
{
597+
/// <summary>
598+
/// Manage a client acquired from the PooledRedisClientManager
599+
/// Dispose method will release the client back to the pool.
600+
/// </summary>
601+
public class DisposablePooledClient<T> : IDisposable where T : RedisNativeClient
602+
{
603+
private T client;
604+
private readonly PooledRedisClientManager clientManager;
605+
606+
/// <summary>
607+
/// wrap the acquired client
608+
/// </summary>
609+
/// <param name="clientManager"></param>
610+
public DisposablePooledClient(PooledRedisClientManager clientManager)
611+
{
612+
this.clientManager = clientManager;
613+
if (clientManager != null)
614+
client = (T)clientManager.GetClient();
615+
}
616+
617+
/// <summary>
618+
/// access the wrapped client
619+
/// </summary>
620+
public T Client { get { return client; } }
621+
622+
/// <summary>
623+
/// release the wrapped client back to the pool
624+
/// </summary>
625+
public void Dispose()
626+
{
627+
if (client != null)
628+
clientManager.DisposeClient(client);
629+
client = null;
630+
}
631+
}
632+
633+
public DisposablePooledClient<T> GetDisposableClient<T>() where T : RedisNativeClient
634+
{
635+
return new DisposablePooledClient<T>(this);
636+
}
637+
}
638+
617639
}

0 commit comments

Comments
 (0)