Skip to content

Instantly share code, notes, and snippets.

@msarchet
Created November 19, 2012 16:25
Show Gist options
  • Save msarchet/4111621 to your computer and use it in GitHub Desktop.
Save msarchet/4111621 to your computer and use it in GitHub Desktop.
An abstraction over ServiceStacks IRedisList to provide cleaner connection handling
/*
** This exists to show differences in how to access HybridList<T> vs the standard IRedisList<T>
*/
//Adding items
//IRedisList<T>
using(var redis = new RedisClient())
{
redis.As<T>().Lists["SomeKey"].Add(newT);
}
//HybridList<T>
(new HybridList<T>("SomeKey").Add(newT);
//Example in a class
//using IRedisList
public class DataStructure
{
public IList<SomeModel> Models
{
get
{
using(var redis = new RedisClient())
{
return redis.As<SomeModel>.Lists["key"].ToList();
}
}
}
public void AddItemToModel(SomeModel newModel)
{
//this has to be done so the redis client is disposed properly
using(var redis = new RedisClient())
{
redis.As<T>().Lists["key"].Add(newModel);
}
}
}
//using HybridList
public class DataStructure
{
public IList<SomeModel> Models { get { return new HybridList<SomeModel>("key"); } }
//AddingItemToModel can be accomplished through the IList<T>.Add call directly
public void AddItemToModel(SomeModel newModel)
{
//The whole method isn't necessary but shown for comparison.
Models.Add(newModel);
}
}
public class HybridList<T> : IList<T>
{
private string _key = null;
private HybridList() { }
public HybridList(string key)
{
_key = key;
}
#region IList<T> Members
private List<T> getRedisList()
{
using(var redis = new RedisClient())
{
var client = redis.As<T>();
return client.Lists[_key].ToList();
}
}
public int IndexOf(T item)
{
return getRedisList().IndexOf(item);
}
public void Insert(int index, T item)
{
using(var redis = new RedisClient())
{
redis.As<T>().Lists[_key].Insert(index, item);
}
}
public void RemoveAt(int index)
{
using(var redis = new RedisClient())
{
redis.As<T>().Lists[_key].RemoveAt(index);
}
}
public T this[int index]
{
get
{
return getRedisList()[index];
}
set
{
using(var redis = new RedisClient())
{
redis.As<T>().Lists[_key][index] = value;
}
}
}
#endregion
#region ICollection<T> Members
public void Add(T item)
{
using(var redis = new RedisClient())
{
redis.As<T>().Lists[_key].Add(item);
}
}
public void Clear()
{
using(var redis = new RedisClient())
{
redis.As<T>().Lists[_key].Clear();
}
}
public bool Contains(T item)
{
return getRedisList().Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
getRedisList().CopyTo(array, arrayIndex);
}
public int Count
{
get { return getRedisList().Count(); }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
using(var redis = new RedisClient())
{
return redis.As<T>().Lists[_key].Remove(item);
}
}
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return getRedisList().GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IEnumerable)getRedisList()).GetEnumerator();
}
#endregion
}
@mythz
Copy link

mythz commented Nov 19, 2012

Okie yeah so it's just a managed proxy.

Unfortunately it creates a new RedisClient() for each operation which means it opens a new TCP connection that only points to localhost:6379, you would want to pass in an IRedisClientsManager to be able to change it so it access it from a configured pool.
Even when using a pool this will have more overhead than the existing impl which just re-uses the open Redis Connection for each operation.

Because it needs a reference to a IRedisClientsManager to be generically useful this is probably best exposed as a (non-invasive) extension method, e.g:

var managedList = redisManager.GetManagedList(key);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment