Reputation: 3018
First, a link to the library: ServiceStack.Redis
now, Im working on some generic cache mechanism which supports, for now, in 4 methods:
Put, Get, PutMany, GetMany
Problem is, whenever I want to insert numerous records, I dont have an option (visible to me) to add an expiration, unlike Put - where I can.
The code is pretty streight forward:
public void PutMany(ICollection<T> items)
{
TimeSpan expiration = GetExpiration();
DateTime expire = DateTime.UtcNow.Add(expiration);
Dictionary<string, CachedItem<T>> dict = new Dictionary<string, CachedItem<T>>();
foreach (T item in items)
{
CachedItem<T> cacheItem = new CachedItem<T>(item, expire);
if (!dict.ContainsKey(cacheItem.Id))
dict.Add(cacheItem.Id, cacheItem);
}
// Store item in cache
_client.SetAll(dict);
}
the model CachedItem<T>
is mine, just imagine it as some sort of an object.
As you can see, I dont have an option of setting the expiration.
Is there a way (besides inserting them 1 by 1 using _client.Set()
) to achieve this?
TIA.
P.S
I know I can store all records in a list or an hash, I dont want that all the records will have a single expiration date (wrong, and can cause very serious performance issues whenever they expire)
Upvotes: 1
Views: 2017
Reputation: 143319
Redis does not have any command that will let you set an expiry with a bulk insert nor does any of its Expire commands allow you to apply the expiry to multiple keys.
To avoid an N+1 operation you'll need to queue multiple SET commands in a Redis Transaction or pipeline, setting each entry individually with an expiry, e.g:
using (var trans = Redis.CreateTransaction())
{
foreach (var entry in dict)
{
trans.QueueCommand(r => r.SetValue(entry.Key, entry.Value, expireIn));
}
trans.Commit();
}
Where ServiceStack.Redis will still send the multiple SET operations in a bulk Redis transaction.
Upvotes: 3