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

Commit cad3f7b

Browse files
committed
Add new Client, Config and Role commands
1 parent 232fccb commit cad3f7b

5 files changed

Lines changed: 287 additions & 52 deletions

File tree

src/ServiceStack.Redis/RedisClient.cs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -189,26 +189,10 @@ public void ChangeDb(long db)
189189
SendExpectSuccess(Commands.Select, db.ToUtf8Bytes());
190190
}
191191

192+
[Obsolete("Use GetClientsInfo")]
192193
public List<Dictionary<string, string>> GetClientList()
193194
{
194-
var clientList = base.ClientList().FromUtf8Bytes();
195-
var results = new List<Dictionary<string, string>>();
196-
197-
var lines = clientList.Split('\n');
198-
foreach (var line in lines)
199-
{
200-
if (String.IsNullOrEmpty(line)) continue;
201-
202-
var map = new Dictionary<string, string>();
203-
var parts = line.Split(' ');
204-
foreach (var part in parts)
205-
{
206-
var keyValue = part.SplitOnFirst('=');
207-
map[keyValue[0]] = keyValue[1];
208-
}
209-
results.Add(map);
210-
}
211-
return results;
195+
return GetClientsInfo();
212196
}
213197

214198
public void SetAll(IEnumerable<string> keys, IEnumerable<string> values)
@@ -365,37 +349,6 @@ public TimeSpan GetTimeToLive(string key)
365349
return TimeSpan.FromSeconds(Ttl(key));
366350
}
367351

368-
public void SetConfig(string configItem, string value)
369-
{
370-
base.ConfigSet(configItem, value.ToUtf8Bytes());
371-
}
372-
373-
public string GetConfig(string configItem)
374-
{
375-
var sb = new StringBuilder();
376-
var byteArray = base.ConfigGet(configItem);
377-
foreach (var bytes in byteArray)
378-
{
379-
if (sb.Length > 0)
380-
sb.Append(" ");
381-
382-
sb.Append(bytes.FromUtf8Bytes());
383-
}
384-
return sb.ToString();
385-
}
386-
387-
public DateTime GetServerTime()
388-
{
389-
var parts = base.Time();
390-
var unixTime = long.Parse(parts[0].FromUtf8Bytes());
391-
var microSecs = long.Parse(parts[1].FromUtf8Bytes());
392-
var ticks = microSecs / 1000 * TimeSpan.TicksPerMillisecond;
393-
394-
var date = unixTime.FromUnixTime();
395-
var timeSpan = TimeSpan.FromTicks(ticks);
396-
return date + timeSpan;
397-
}
398-
399352
public IRedisTypedClient<T> As<T>()
400353
{
401354
try

src/ServiceStack.Redis/RedisClientManagerCacheClient.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
namespace ServiceStack.Redis
66
{
7+
/// <summary>
8+
/// For interoperabilty GetCacheClient() and GetReadOnlyCacheClient()
9+
/// return an ICacheClient wrapper around the redis manager which has the affect of calling
10+
/// GetClient() for all write operations and GetReadOnlyClient() for the read ones.
11+
///
12+
/// This works well for master-slave replication scenarios where you have
13+
/// 1 master that replicates to multiple read slaves.
14+
/// </summary>
715
public class RedisClientManagerCacheClient : ICacheClient, IRemoveByPattern
816
{
917
private readonly IRedisClientsManager redisManager;
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//
2+
// https://github.com/ServiceStack/ServiceStack.Redis
3+
// ServiceStack.Redis: ECMA CLI Binding to the Redis key-value storage system
4+
//
5+
// Authors:
6+
// Demis Bellot (demis.bellot@gmail.com)
7+
//
8+
// Copyright 2013 Service Stack LLC. All Rights Reserved.
9+
//
10+
// Licensed under the same terms of ServiceStack.
11+
//
12+
13+
using System;
14+
using System.Collections.Generic;
15+
using System.Text;
16+
using ServiceStack.Text;
17+
18+
namespace ServiceStack.Redis
19+
{
20+
public partial class RedisClient
21+
: IRedisClient
22+
{
23+
public void SetConfig(string configItem, string value)
24+
{
25+
base.ConfigSet(configItem, value.ToUtf8Bytes());
26+
}
27+
28+
public RedisText GetServerRoleInfo()
29+
{
30+
return base.Role();
31+
}
32+
33+
public string GetConfig(string configItem)
34+
{
35+
var sb = new StringBuilder();
36+
var byteArray = base.ConfigGet(configItem);
37+
const int startAt = 1; //skip repeating config name
38+
for (var i = startAt; i < byteArray.Length; i++)
39+
{
40+
var bytes = byteArray[i];
41+
if (sb.Length > 0)
42+
sb.Append(" ");
43+
44+
sb.Append(bytes.FromUtf8Bytes());
45+
}
46+
return sb.ToString();
47+
}
48+
49+
public void SaveConfig()
50+
{
51+
base.ConfigRewrite();
52+
}
53+
54+
public void ResetInfoStats()
55+
{
56+
base.ConfigResetStat();
57+
}
58+
59+
public string GetClient()
60+
{
61+
return base.ClientGetName();
62+
}
63+
64+
public void SetClient(string name)
65+
{
66+
base.ClientSetName(name);
67+
}
68+
69+
public void KillClient(string address)
70+
{
71+
base.ClientKill(address);
72+
}
73+
74+
public long KillClients(string fromAddress = null, string withId = null, RedisClientType? ofType = null, bool? skipMe = null)
75+
{
76+
var typeString = ofType != null ? ofType.ToString().ToLower() : null;
77+
var skipMeString = skipMe != null ? (skipMe.Value ? "yes" : "no") : null;
78+
return base.ClientKill(addr: fromAddress, id: withId, type: typeString, skipMe: skipMeString);
79+
}
80+
81+
public List<Dictionary<string, string>> GetClientsInfo()
82+
{
83+
var clientList = base.ClientList().FromUtf8Bytes();
84+
var results = new List<Dictionary<string, string>>();
85+
86+
var lines = clientList.Split('\n');
87+
foreach (var line in lines)
88+
{
89+
if (String.IsNullOrEmpty(line)) continue;
90+
91+
var map = new Dictionary<string, string>();
92+
var parts = line.Split(' ');
93+
foreach (var part in parts)
94+
{
95+
var keyValue = part.SplitOnFirst('=');
96+
map[keyValue[0]] = keyValue[1];
97+
}
98+
results.Add(map);
99+
}
100+
return results;
101+
}
102+
103+
public void PauseAllClients(TimeSpan duration)
104+
{
105+
base.ClientPause((int)duration.TotalMilliseconds);
106+
}
107+
108+
public DateTime GetServerTime()
109+
{
110+
var parts = base.Time();
111+
var unixTime = long.Parse(parts[0].FromUtf8Bytes());
112+
var microSecs = long.Parse(parts[1].FromUtf8Bytes());
113+
var ticks = microSecs / 1000 * TimeSpan.TicksPerMillisecond;
114+
115+
var date = unixTime.FromUnixTime();
116+
var timeSpan = TimeSpan.FromTicks(ticks);
117+
return date + timeSpan;
118+
}
119+
}
120+
}

src/ServiceStack.Redis/RedisNativeClient.cs

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public partial class RedisNativeClient
6262
/// Used to manage connection pooling
6363
/// </summary>
6464
internal bool Active { get; set; }
65-
internal PooledRedisClientManager ClientManager { get; set; }
65+
internal IHandleClientDispose ClientManager { get; set; }
6666

6767
internal long LastConnectedAtTimestamp;
6868

@@ -82,6 +82,7 @@ public partial class RedisNativeClient
8282
public int SendTimeout { get; set; }
8383
public int ReceiveTimeout { get; set; }
8484
public string Password { get; set; }
85+
public string Client { get; set; }
8586
public int IdleTimeOutSecs { get; set; }
8687

8788
public Action<IRedisNativeClient> ConnectionFilter { get; set; }
@@ -138,9 +139,12 @@ private void Init(RedisEndpoint config)
138139
{
139140
Host = config.Host;
140141
Port = config.Port;
142+
ConnectTimeout = config.ConnectTimeout;
141143
SendTimeout = config.SendTimeout;
142144
ReceiveTimeout = config.ReceiveTimeout;
143145
Password = config.Password;
146+
NamespacePrefix = config.NamespacePrefix;
147+
Client = config.Client;
144148
Db = config.Db;
145149
Ssl = config.Ssl;
146150
IdleTimeOutSecs = config.IdleTimeOutSecs;
@@ -249,7 +253,12 @@ public void ConfigResetStat()
249253
SendExpectSuccess(Commands.Config, Commands.ResetStat);
250254
}
251255

252-
public byte[][] Time()
256+
public void ConfigRewrite()
257+
{
258+
SendExpectSuccess(Commands.Config, Commands.Rewrite);
259+
}
260+
261+
public byte[][] Time()
253262
{
254263
return SendExpectMultiData(Commands.Time);
255264
}
@@ -296,7 +305,7 @@ public long ObjectIdleTime(string key)
296305
return SendExpectLong(Commands.Object, Commands.IdleTime, key.ToUtf8Bytes());
297306
}
298307

299-
public string Type(string key)
308+
public string Type(string key)
300309
{
301310
if (key == null)
302311
throw new ArgumentNullException("key");
@@ -714,6 +723,11 @@ public void FlushAll()
714723
SendExpectSuccess(Commands.FlushAll);
715724
}
716725

726+
public RedisText Role()
727+
{
728+
return SendExpectComplexResponse(Commands.Role).ToRedisText();
729+
}
730+
717731
public string ClientGetName()
718732
{
719733
return SendExpectString(Commands.Client, Commands.GetName);
@@ -730,6 +744,11 @@ public void ClientSetName(string name)
730744
SendExpectSuccess(Commands.Client, Commands.SetName, name.ToUtf8Bytes());
731745
}
732746

747+
public void ClientPause(int timeOutMs)
748+
{
749+
SendExpectSuccess(Commands.Client, Commands.Pause, timeOutMs.ToUtf8Bytes());
750+
}
751+
733752
public byte[] ClientList()
734753
{
735754
return SendExpectData(Commands.Client, Commands.List);
@@ -740,6 +759,40 @@ public void ClientKill(string clientAddr)
740759
SendExpectSuccess(Commands.Client, Commands.Kill, clientAddr.ToUtf8Bytes());
741760
}
742761

762+
public long ClientKill(string addr = null, string id = null, string type = null, string skipMe = null)
763+
{
764+
var cmdWithArgs = new List<byte[]>
765+
{
766+
Commands.Client, Commands.Kill,
767+
};
768+
769+
if (addr != null)
770+
{
771+
cmdWithArgs.Add(Commands.Addr);
772+
cmdWithArgs.Add(addr.ToUtf8Bytes());
773+
}
774+
775+
if (id != null)
776+
{
777+
cmdWithArgs.Add(Commands.Id);
778+
cmdWithArgs.Add(id.ToUtf8Bytes());
779+
}
780+
781+
if (type != null)
782+
{
783+
cmdWithArgs.Add(Commands.Type);
784+
cmdWithArgs.Add(type.ToUtf8Bytes());
785+
}
786+
787+
if (skipMe != null)
788+
{
789+
cmdWithArgs.Add(Commands.SkipMe);
790+
cmdWithArgs.Add(skipMe.ToUtf8Bytes());
791+
}
792+
793+
return SendExpectLong(cmdWithArgs.ToArray());
794+
}
795+
743796
public byte[][] Keys(string pattern)
744797
{
745798
if (pattern == null)

0 commit comments

Comments
 (0)